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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 bool RecordInfo::InheritsNonPureTrace() { | 187 bool RecordInfo::InheritsNonPureTrace() { |
188 if (CXXMethodDecl* trace = GetTraceMethod()) | 188 if (CXXMethodDecl* trace = GetTraceMethod()) |
189 return !trace->isPure(); | 189 return !trace->isPure(); |
190 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | 190 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
191 if (it->second.info()->InheritsNonPureTrace()) | 191 if (it->second.info()->InheritsNonPureTrace()) |
192 return true; | 192 return true; |
193 } | 193 } |
194 return false; | 194 return false; |
195 } | 195 } |
196 | 196 |
197 CXXMethodDecl* RecordInfo::InheritsNonVirtualTrace() { | |
198 if (CXXMethodDecl* trace = GetTraceMethod()) | |
199 return trace->isVirtual() ? 0 : trace; | |
200 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | |
201 if (CXXMethodDecl* trace = it->second.info()->InheritsNonVirtualTrace()) | |
202 return trace; | |
203 } | |
204 return 0; | |
205 } | |
206 | |
207 // A (non-virtual) class is considered abstract in Blink if it has | |
208 // no public constructors and no create methods. | |
209 bool RecordInfo::IsConsideredAbstract() { | |
210 for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin(); | |
211 it != record_->ctor_end(); | |
212 ++it) { | |
213 if (!it->isCopyOrMoveConstructor() && it->getAccess() == AS_public) | |
214 return false; | |
215 } | |
216 for (CXXRecordDecl::method_iterator it = record_->method_begin(); | |
217 it != record_->method_end(); | |
218 ++it) { | |
219 if (it->getNameAsString() == kCreateName) | |
220 return false; | |
221 } | |
222 return true; | |
223 } | |
224 | |
197 RecordInfo::Bases* RecordInfo::CollectBases() { | 225 RecordInfo::Bases* RecordInfo::CollectBases() { |
198 // Compute the collection locally to avoid inconsistent states. | 226 // Compute the collection locally to avoid inconsistent states. |
199 Bases* bases = new Bases; | 227 Bases* bases = new Bases; |
200 if (!record_->hasDefinition()) | 228 if (!record_->hasDefinition()) |
201 return bases; | 229 return bases; |
202 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); | 230 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); |
203 it != record_->bases_end(); | 231 it != record_->bases_end(); |
204 ++it) { | 232 ++it) { |
205 const CXXBaseSpecifier& spec = *it; | 233 const CXXBaseSpecifier& spec = *it; |
206 RecordInfo* info = cache_->Lookup(spec.getType()); | 234 RecordInfo* info = cache_->Lookup(spec.getType()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 if (determined_trace_methods_) | 275 if (determined_trace_methods_) |
248 return; | 276 return; |
249 determined_trace_methods_ = true; | 277 determined_trace_methods_ = true; |
250 CXXMethodDecl* trace = 0; | 278 CXXMethodDecl* trace = 0; |
251 CXXMethodDecl* traceAfterDispatch = 0; | 279 CXXMethodDecl* traceAfterDispatch = 0; |
252 bool isTraceAfterDispatch; | 280 bool isTraceAfterDispatch; |
253 for (CXXRecordDecl::method_iterator it = record_->method_begin(); | 281 for (CXXRecordDecl::method_iterator it = record_->method_begin(); |
254 it != record_->method_end(); | 282 it != record_->method_end(); |
255 ++it) { | 283 ++it) { |
256 if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { | 284 if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { |
257 // TODO: Test that the formal parameter is of type Visitor*. | |
258 if (isTraceAfterDispatch) { | 285 if (isTraceAfterDispatch) { |
259 traceAfterDispatch = *it; | 286 traceAfterDispatch = *it; |
260 } else { | 287 } else { |
261 trace = *it; | 288 trace = *it; |
262 } | 289 } |
263 } | 290 } |
264 } | 291 } |
265 if (traceAfterDispatch) { | 292 if (traceAfterDispatch) { |
266 trace_method_ = traceAfterDispatch; | 293 trace_method_ = traceAfterDispatch; |
267 trace_dispatch_method_ = trace; | 294 trace_dispatch_method_ = trace; |
268 } else { | 295 } else { |
269 // TODO: Can we never have a dispatch method called trace without the same | 296 // TODO: Can we never have a dispatch method called trace without the same |
270 // class defining a traceAfterDispatch method? | 297 // class defining a traceAfterDispatch method? |
271 trace_method_ = trace; | 298 trace_method_ = trace; |
272 trace_dispatch_method_ = 0; | 299 trace_dispatch_method_ = 0; |
273 } | 300 } |
301 if (trace_dispatch_method_) | |
302 return; | |
Mads Ager (chromium)
2014/03/18 09:19:32
How about removing this and instead moving the bel
zerny-chromium
2014/03/18 10:03:41
The for loop might need to run in either branch si
| |
303 // If this class does not define a trace dispatch method search inherit it. | |
Mads Ager (chromium)
2014/03/18 09:19:32
search the inheritance hierarchy for it?
zerny-chromium
2014/03/18 10:03:41
Yes. Thanks.
| |
304 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | |
305 if (CXXMethodDecl* dispatch = it->second.info()->GetTraceDispatchMethod()) { | |
306 // TODO: Does it make sense to inherit multiple dispatch methods? | |
307 assert(!trace_dispatch_method_ && "Multiple trace dispatching methods"); | |
308 trace_dispatch_method_ = dispatch; | |
309 } | |
310 } | |
274 } | 311 } |
275 | 312 |
276 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. | 313 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. |
277 bool RecordInfo::NeedsFinalization() { | 314 bool RecordInfo::NeedsFinalization() { |
278 return record_->hasNonTrivialDestructor(); | 315 return record_->hasNonTrivialDestructor(); |
279 } | 316 } |
280 | 317 |
281 // A class needs tracing if: | 318 // A class needs tracing if: |
282 // - it is allocated on the managed heap, | 319 // - it is allocated on the managed heap, |
283 // - it is derived from a class that needs tracing, or | 320 // - it is derived from a class that needs tracing, or |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 // We failed to create an edge so abort the entire edge construction. | 417 // We failed to create an edge so abort the entire edge construction. |
381 delete edge; // Will delete the already allocated members. | 418 delete edge; // Will delete the already allocated members. |
382 return 0; | 419 return 0; |
383 } | 420 } |
384 } | 421 } |
385 return edge; | 422 return edge; |
386 } | 423 } |
387 | 424 |
388 return new Value(info); | 425 return new Value(info); |
389 } | 426 } |
OLD | NEW |