Index: tools/clang/blink_gc_plugin/RecordInfo.cpp |
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp |
index 3c166dd4c431374f32ff2851d01654c82d7a805a..5d3aa4776abf2d73bd1c71defe6b39499d50e961 100644 |
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp |
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp |
@@ -15,6 +15,7 @@ RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) |
fields_need_tracing_(TracingStatus::Unknown()), |
bases_(0), |
fields_(0), |
+ field_map_(0), |
is_stack_allocated_(kNotComputed), |
is_non_newable_(kNotComputed), |
is_only_placement_newable_(kNotComputed), |
@@ -30,6 +31,7 @@ RecordInfo::RecordInfo(CXXRecordDecl* record, RecordCache* cache) |
RecordInfo::~RecordInfo() { |
delete fields_; |
+ delete field_map_; |
delete bases_; |
} |
@@ -319,7 +321,7 @@ CXXMethodDecl* RecordInfo::GetFinalizeDispatchMethod() { |
RecordInfo::Bases& RecordInfo::GetBases() { |
if (!bases_) |
- bases_ = CollectBases(); |
+ CollectBases(); |
return *bases_; |
} |
@@ -383,11 +385,12 @@ bool RecordInfo::IsConsideredAbstract() { |
return true; |
} |
-RecordInfo::Bases* RecordInfo::CollectBases() { |
+void RecordInfo::CollectBases() { |
// Compute the collection locally to avoid inconsistent states. |
- Bases* bases = new Bases; |
+ assert(!bases_); |
+ bases_ = new Bases; |
if (!record_->hasDefinition()) |
- return bases; |
+ return; |
for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); |
it != record_->bases_end(); |
++it) { |
@@ -399,22 +402,38 @@ RecordInfo::Bases* RecordInfo::CollectBases() { |
TracingStatus status = info->InheritsTrace() |
? TracingStatus::Needed() |
: TracingStatus::Unneeded(); |
- bases->insert(std::make_pair(base, BasePoint(spec, info, status))); |
+ bases_->push_back(std::make_pair(base, BasePoint(spec, info, status))); |
} |
- return bases; |
} |
RecordInfo::Fields& RecordInfo::GetFields() { |
- if (!fields_) |
- fields_ = CollectFields(); |
+ if (!fields_) { |
+ assert(!field_map_); |
+ CollectFields(); |
+ } |
return *fields_; |
} |
-RecordInfo::Fields* RecordInfo::CollectFields() { |
+bool RecordInfo::HasField(clang::FieldDecl* field) { |
+ GetFields(); |
+ assert(field_map_); |
+ return field_map_->count(field); |
+} |
+ |
+RecordInfo::Field& RecordInfo::GetField(clang::FieldDecl* field) { |
+ assert(HasField(field)); |
+ return fields_->at((*field_map_)[field]); |
+} |
+ |
+void RecordInfo::CollectFields() { |
// Compute the collection locally to avoid inconsistent states. |
- Fields* fields = new Fields; |
+ assert(!fields_); |
+ fields_ = new Fields; |
+ field_map_ = new std::map<clang::FieldDecl*, size_t>; |
+ |
if (!record_->hasDefinition()) |
- return fields; |
+ return; |
+ |
TracingStatus fields_status = TracingStatus::Unneeded(); |
for (RecordDecl::field_iterator it = record_->field_begin(); |
it != record_->field_end(); |
@@ -425,11 +444,11 @@ RecordInfo::Fields* RecordInfo::CollectFields() { |
continue; |
if (Edge* edge = CreateEdge(field->getType().getTypePtrOrNull())) { |
fields_status = fields_status.LUB(edge->NeedsTracing(Edge::kRecursive)); |
- fields->insert(std::make_pair(field, FieldPoint(field, edge))); |
+ (*field_map_)[field] = fields_->size(); |
+ fields_->push_back(std::make_pair(field, FieldPoint(field, edge))); |
} |
} |
fields_need_tracing_ = fields_status; |
- return fields; |
} |
void RecordInfo::DetermineTracingMethods() { |