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 #include "clang/AST/Attr.h" | 8 #include "clang/AST/Attr.h" |
9 | 9 |
10 using namespace clang; | 10 using namespace clang; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 167 } |
168 return false; | 168 return false; |
169 } | 169 } |
170 | 170 |
171 RecordInfo::Bases* RecordInfo::CollectBases() { | 171 RecordInfo::Bases* RecordInfo::CollectBases() { |
172 // Compute the collection locally to avoid inconsistent states. | 172 // Compute the collection locally to avoid inconsistent states. |
173 Bases* bases = new Bases; | 173 Bases* bases = new Bases; |
174 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); | 174 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); |
175 it != record_->bases_end(); | 175 it != record_->bases_end(); |
176 ++it) { | 176 ++it) { |
177 if (CXXRecordDecl* base = it->getType()->getAsCXXRecordDecl()) { | 177 const CXXBaseSpecifier& spec = *it; |
| 178 if (CXXRecordDecl* base = spec.getType()->getAsCXXRecordDecl()) { |
178 RecordInfo* info = cache_->Lookup(base); | 179 RecordInfo* info = cache_->Lookup(base); |
179 TracingStatus status = info->InheritsNonPureTrace() | 180 TracingStatus status = info->InheritsNonPureTrace() |
180 ? TracingStatus::Needed() | 181 ? TracingStatus::Needed() |
181 : TracingStatus::Unneeded(); | 182 : TracingStatus::Unneeded(); |
182 bases->insert(std::make_pair(base, BasePoint(info, status))); | 183 bases->insert(std::make_pair(base, BasePoint(spec, info, status))); |
183 } | 184 } |
184 } | 185 } |
185 return bases; | 186 return bases; |
186 } | 187 } |
187 | 188 |
188 RecordInfo::Fields& RecordInfo::GetFields() { | 189 RecordInfo::Fields& RecordInfo::GetFields() { |
189 if (!fields_) | 190 if (!fields_) |
190 fields_ = CollectFields(); | 191 fields_ = CollectFields(); |
191 return *fields_; | 192 return *fields_; |
192 } | 193 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 trace_method_ = traceAfterDispatch; | 235 trace_method_ = traceAfterDispatch; |
235 trace_dispatch_method_ = trace; | 236 trace_dispatch_method_ = trace; |
236 } else { | 237 } else { |
237 // TODO: Can we never have a dispatch method called trace without the same | 238 // TODO: Can we never have a dispatch method called trace without the same |
238 // class defining a traceAfterDispatch method? | 239 // class defining a traceAfterDispatch method? |
239 trace_method_ = trace; | 240 trace_method_ = trace; |
240 trace_dispatch_method_ = 0; | 241 trace_dispatch_method_ = 0; |
241 } | 242 } |
242 } | 243 } |
243 | 244 |
| 245 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. |
| 246 bool RecordInfo::NeedsFinalization() { |
| 247 return record_->hasNonTrivialDestructor(); |
| 248 } |
| 249 |
244 // A class needs tracing if: | 250 // A class needs tracing if: |
245 // - it is allocated on the managed heap, | 251 // - it is allocated on the managed heap, |
246 // - it defines a trace method (of the proper signature), or | 252 // - it defines a trace method (of the proper signature), or |
247 // - it contains fields that need tracing. | 253 // - it contains fields that need tracing. |
248 TracingStatus RecordInfo::NeedsTracing(Edge::NeedsTracingOption option) { | 254 TracingStatus RecordInfo::NeedsTracing(Edge::NeedsTracingOption option) { |
249 if (IsGCAllocated() || GetTraceMethod()) | 255 if (IsGCAllocated() || GetTraceMethod()) |
250 return TracingStatus::Needed(); | 256 return TracingStatus::Needed(); |
251 | 257 |
252 if (option == Edge::kRecursive) | 258 if (option == Edge::kRecursive) |
253 GetFields(); | 259 GetFields(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 return 0; | 327 return 0; |
322 } | 328 } |
323 | 329 |
324 if (Config::IsGCCollection(info->name()) || | 330 if (Config::IsGCCollection(info->name()) || |
325 Config::IsWTFCollection(info->name())) { | 331 Config::IsWTFCollection(info->name())) { |
326 bool is_root = Config::IsPersistentGCCollection(info->name()); | 332 bool is_root = Config::IsPersistentGCCollection(info->name()); |
327 bool on_heap = is_root || info->IsHeapAllocatedCollection(); | 333 bool on_heap = is_root || info->IsHeapAllocatedCollection(); |
328 size_t count = Config::CollectionDimension(info->name()); | 334 size_t count = Config::CollectionDimension(info->name()); |
329 if (!info->GetTemplateArgs(count, &args)) | 335 if (!info->GetTemplateArgs(count, &args)) |
330 return 0; | 336 return 0; |
331 Collection* edge = new Collection(on_heap, is_root); | 337 Collection* edge = new Collection(info, on_heap, is_root); |
332 for (TemplateArgs::iterator it = args.begin(); it != args.end(); ++it) { | 338 for (TemplateArgs::iterator it = args.begin(); it != args.end(); ++it) { |
333 if (Edge* member = CreateEdge(*it)) { | 339 if (Edge* member = CreateEdge(*it)) { |
334 edge->members().push_back(member); | 340 edge->members().push_back(member); |
335 } else { | 341 } else { |
336 // We failed to create an edge so abort the entire edge construction. | 342 // We failed to create an edge so abort the entire edge construction. |
337 delete edge; // Will delete the already allocated members. | 343 delete edge; // Will delete the already allocated members. |
338 return 0; | 344 return 0; |
339 } | 345 } |
340 } | 346 } |
341 return edge; | 347 return edge; |
342 } | 348 } |
343 | 349 |
344 return new Value(info); | 350 return new Value(info); |
345 } | 351 } |
OLD | NEW |