Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: tools/clang/blink_gc_plugin/RecordInfo.cpp

Issue 374593002: Support ignorance of base class finalizers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reworked, static check now expressed by RecordInfo::NeedsFinalization() Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 determined_trace_methods_(false), 22 determined_trace_methods_(false),
22 trace_method_(0), 23 trace_method_(0),
23 trace_dispatch_method_(0), 24 trace_dispatch_method_(0),
24 finalize_dispatch_method_(0), 25 finalize_dispatch_method_(0),
25 is_gc_derived_(false), 26 is_gc_derived_(false),
26 base_paths_(0) {} 27 base_paths_(0) {}
27 28
28 RecordInfo::~RecordInfo() { 29 RecordInfo::~RecordInfo() {
29 delete fields_; 30 delete fields_;
30 delete bases_; 31 delete bases_;
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 it->second.info()->GetFinalizeDispatchMethod()) { 394 it->second.info()->GetFinalizeDispatchMethod()) {
394 assert(!finalize_dispatch_method_ && 395 assert(!finalize_dispatch_method_ &&
395 "Multiple finalize dispatching methods"); 396 "Multiple finalize dispatching methods");
396 finalize_dispatch_method_ = dispatch; 397 finalize_dispatch_method_ = dispatch;
397 } 398 }
398 } 399 }
399 } 400 }
400 401
401 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. 402 // TODO: Add classes with a finalize() method that specialize FinalizerTrait.
402 bool RecordInfo::NeedsFinalization() { 403 bool RecordInfo::NeedsFinalization() {
403 return record_->hasNonTrivialDestructor(); 404 if (does_need_finalization_ == kNotComputed) {
405 // Rely on hasNonTrivialDestructor(), but if the only
406 // identifiable reason why it is true is the presence
407 // of a class with a safely ignorable class as a direct base,
408 // or such a class is being represented here, then it does
409 // not need finalization.
410 does_need_finalization_ =
411 record_->hasNonTrivialDestructor() ? kTrue : kFalse;
412 if (does_need_finalization_) {
zerny-chromium 2014/07/08 07:45:03 Add early exit instead: if (!does_need_finalizati
sof 2014/07/08 08:47:05 Rephrased to use early returns instead of fallthro
413 // Checking if processing a class with a safely-ignorable destructor.
414 NamespaceDecl* ns =
415 dyn_cast<NamespaceDecl>(record_->getDeclContext());
416 if (ns && Config::HasIgnorableDestructor(ns->getName(), name_))
417 does_need_finalization_ = kFalse;
zerny-chromium 2014/07/08 07:45:02 Do an early return in this block as well and avoid
418 }
419 if (does_need_finalization_) {
420 CXXDestructorDecl* dtor = record_->getDestructor();
421 bool is_candidate = !dtor || !dtor->isUserProvided();
422 for (Fields::iterator it = GetFields().begin();
423 is_candidate && it != GetFields().end();
424 ++it) {
425 if (it->second.edge()->NeedsFinalization())
426 is_candidate = false;
zerny-chromium 2014/07/08 07:45:03 This can just return does_need_finalization_ which
427 }
428
429 for (Bases::iterator it = GetBases().begin();
430 is_candidate && it != GetBases().end();
431 ++it) {
432 NamespaceDecl* ns = dyn_cast<NamespaceDecl>(
433 it->second.info()->record()->getDeclContext());
434 if (ns &&
zerny-chromium 2014/07/08 07:45:03 This check is not be needed here. The ignored case
sof 2014/07/08 08:47:05 I was hesitant to remove it, in case the complete
sof 2014/07/08 08:48:49 s/in case/in scope/. Need more coffee.
435 Config::HasIgnorableDestructor(ns->getName(),
436 it->second.info()->name()))
437 continue;
438 if (it->second.info()->NeedsFinalization())
439 is_candidate = false;
zerny-chromium 2014/07/08 07:45:02 Just return does_need_finalization_
440 }
441 if (is_candidate)
zerny-chromium 2014/07/08 07:45:02 Here we can unconditionally set does_need_finaliza
442 does_need_finalization_ = kFalse;
443 }
444 }
445 return does_need_finalization_;
404 } 446 }
405 447
406 // A class needs tracing if: 448 // A class needs tracing if:
407 // - it is allocated on the managed heap, 449 // - it is allocated on the managed heap,
408 // - it is derived from a class that needs tracing, or 450 // - it is derived from a class that needs tracing, or
409 // - it contains fields that need tracing. 451 // - it contains fields that need tracing.
410 // TODO: Defining NeedsTracing based on whether a class defines a trace method 452 // TODO: Defining NeedsTracing based on whether a class defines a trace method
411 // (of the proper signature) over approximates too much. The use of transition 453 // (of the proper signature) over approximates too much. The use of transition
412 // types causes some classes to have trace methods without them needing to be 454 // types causes some classes to have trace methods without them needing to be
413 // traced. 455 // traced.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 edge->members().push_back(member); 548 edge->members().push_back(member);
507 } 549 }
508 // TODO: Handle the case where we fail to create an edge (eg, if the 550 // TODO: Handle the case where we fail to create an edge (eg, if the
509 // argument is a primitive type or just not fully known yet). 551 // argument is a primitive type or just not fully known yet).
510 } 552 }
511 return edge; 553 return edge;
512 } 554 }
513 555
514 return new Value(info); 556 return new Value(info);
515 } 557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698