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 |