| 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 |
| 11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) | 11 RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) |
| 12 : cache_(cache), | 12 : cache_(cache), |
| 13 record_(record), | 13 record_(record), |
| 14 name_(record->getName()), | 14 name_(record->getName()), |
| 15 fields_need_tracing_(TracingStatus::Unknown()), | 15 fields_need_tracing_(TracingStatus::Unknown()), |
| 16 bases_(0), | 16 bases_(0), |
| 17 fields_(0), | 17 fields_(0), |
| 18 is_stack_allocated_(kNotComputed), | 18 is_stack_allocated_(kNotComputed), |
| 19 is_non_newable_(kNotComputed), | 19 is_non_newable_(kNotComputed), |
| 20 is_only_placement_newable_(kNotComputed), | 20 is_only_placement_newable_(kNotComputed), |
| 21 does_need_finalization_(kNotComputed), | 21 does_need_finalization_(kNotComputed), |
| 22 has_gc_mixin_methods_(kNotComputed), | 22 has_gc_mixin_methods_(kNotComputed), |
| 23 is_declaring_local_trace_(kNotComputed), | 23 is_declaring_local_trace_(kNotComputed), |
| 24 is_eagerly_finalized_(kNotComputed), |
| 24 determined_trace_methods_(false), | 25 determined_trace_methods_(false), |
| 25 trace_method_(0), | 26 trace_method_(0), |
| 26 trace_dispatch_method_(0), | 27 trace_dispatch_method_(0), |
| 27 finalize_dispatch_method_(0), | 28 finalize_dispatch_method_(0), |
| 28 is_gc_derived_(false) {} | 29 is_gc_derived_(false) {} |
| 29 | 30 |
| 30 RecordInfo::~RecordInfo() { | 31 RecordInfo::~RecordInfo() { |
| 31 delete fields_; | 32 delete fields_; |
| 32 delete bases_; | 33 delete bases_; |
| 33 } | 34 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 } | 162 } |
| 162 // This is a mixin if all GC bases are mixins. | 163 // This is a mixin if all GC bases are mixins. |
| 163 return true; | 164 return true; |
| 164 } | 165 } |
| 165 | 166 |
| 166 // Test if a record is allocated on the managed heap. | 167 // Test if a record is allocated on the managed heap. |
| 167 bool RecordInfo::IsGCAllocated() { | 168 bool RecordInfo::IsGCAllocated() { |
| 168 return IsGCDerived() || IsHeapAllocatedCollection(); | 169 return IsGCDerived() || IsHeapAllocatedCollection(); |
| 169 } | 170 } |
| 170 | 171 |
| 172 bool RecordInfo::IsEagerlyFinalized() { |
| 173 if (is_eagerly_finalized_ == kNotComputed) { |
| 174 is_eagerly_finalized_ = kFalse; |
| 175 if (IsGCFinalized()) { |
| 176 for (Decl* decl : record_->decls()) { |
| 177 if (TypedefDecl* typedef_decl = dyn_cast<TypedefDecl>(decl)) { |
| 178 if (typedef_decl->getNameAsString() == kIsEagerlyFinalizedName) { |
| 179 is_eagerly_finalized_ = kTrue; |
| 180 break; |
| 181 } |
| 182 } |
| 183 } |
| 184 } |
| 185 } |
| 186 return is_eagerly_finalized_; |
| 187 } |
| 188 |
| 189 bool RecordInfo::HasDefinition() { |
| 190 return record_->hasDefinition(); |
| 191 } |
| 192 |
| 171 RecordInfo* RecordCache::Lookup(CXXRecordDecl* record) { | 193 RecordInfo* RecordCache::Lookup(CXXRecordDecl* record) { |
| 172 // Ignore classes annotated with the GC_PLUGIN_IGNORE macro. | 194 // Ignore classes annotated with the GC_PLUGIN_IGNORE macro. |
| 173 if (!record || Config::IsIgnoreAnnotated(record)) | 195 if (!record || Config::IsIgnoreAnnotated(record)) |
| 174 return 0; | 196 return 0; |
| 175 Cache::iterator it = cache_.find(record); | 197 Cache::iterator it = cache_.find(record); |
| 176 if (it != cache_.end()) | 198 if (it != cache_.end()) |
| 177 return &it->second; | 199 return &it->second; |
| 178 return &cache_.insert(std::make_pair(record, RecordInfo(record, this))) | 200 return &cache_.insert(std::make_pair(record, RecordInfo(record, this))) |
| 179 .first->second; | 201 .first->second; |
| 180 } | 202 } |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 GetFields(); | 585 GetFields(); |
| 564 | 586 |
| 565 return fields_need_tracing_; | 587 return fields_need_tracing_; |
| 566 } | 588 } |
| 567 | 589 |
| 568 Edge* RecordInfo::CreateEdge(const Type* type) { | 590 Edge* RecordInfo::CreateEdge(const Type* type) { |
| 569 if (!type) { | 591 if (!type) { |
| 570 return 0; | 592 return 0; |
| 571 } | 593 } |
| 572 | 594 |
| 573 if (type->isPointerType()) { | 595 if (type->isPointerType() || type->isReferenceType()) { |
| 574 if (Edge* ptr = CreateEdge(type->getPointeeType().getTypePtrOrNull())) | 596 if (Edge* ptr = CreateEdge(type->getPointeeType().getTypePtrOrNull())) |
| 575 return new RawPtr(ptr, false); | 597 return new RawPtr(ptr, false, type->isReferenceType()); |
| 576 return 0; | 598 return 0; |
| 577 } | 599 } |
| 578 | 600 |
| 579 RecordInfo* info = cache_->Lookup(type); | 601 RecordInfo* info = cache_->Lookup(type); |
| 580 | 602 |
| 581 // If the type is neither a pointer or a C++ record we ignore it. | 603 // If the type is neither a pointer or a C++ record we ignore it. |
| 582 if (!info) { | 604 if (!info) { |
| 583 return 0; | 605 return 0; |
| 584 } | 606 } |
| 585 | 607 |
| 586 TemplateArgs args; | 608 TemplateArgs args; |
| 587 | 609 |
| 588 if (Config::IsRawPtr(info->name()) && info->GetTemplateArgs(1, &args)) { | 610 if (Config::IsRawPtr(info->name()) && info->GetTemplateArgs(1, &args)) { |
| 589 if (Edge* ptr = CreateEdge(args[0])) | 611 if (Edge* ptr = CreateEdge(args[0])) |
| 590 return new RawPtr(ptr, true); | 612 return new RawPtr(ptr, true, false); |
| 591 return 0; | 613 return 0; |
| 592 } | 614 } |
| 593 | 615 |
| 594 if (Config::IsRefPtr(info->name()) && info->GetTemplateArgs(1, &args)) { | 616 if (Config::IsRefPtr(info->name()) && info->GetTemplateArgs(1, &args)) { |
| 595 if (Edge* ptr = CreateEdge(args[0])) | 617 if (Edge* ptr = CreateEdge(args[0])) |
| 596 return new RefPtr(ptr); | 618 return new RefPtr(ptr); |
| 597 return 0; | 619 return 0; |
| 598 } | 620 } |
| 599 | 621 |
| 600 if (Config::IsOwnPtr(info->name()) && info->GetTemplateArgs(1, &args)) { | 622 if (Config::IsOwnPtr(info->name()) && info->GetTemplateArgs(1, &args)) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 edge->members().push_back(member); | 664 edge->members().push_back(member); |
| 643 } | 665 } |
| 644 // TODO: Handle the case where we fail to create an edge (eg, if the | 666 // TODO: Handle the case where we fail to create an edge (eg, if the |
| 645 // argument is a primitive type or just not fully known yet). | 667 // argument is a primitive type or just not fully known yet). |
| 646 } | 668 } |
| 647 return edge; | 669 return edge; |
| 648 } | 670 } |
| 649 | 671 |
| 650 return new Value(info); | 672 return new Value(info); |
| 651 } | 673 } |
| OLD | NEW |