CXXMethodDecl* RecordInfo::DeclaresNewOperator() { for (CXXRecordDecl::method_iterator it = record_->method_begin(); it != record_->method_end(); ++it) { if (it->getNameAsString() == kNewOperatorName && it->getNumParams() == 1) return *it; } return 0; }
// A (non-virtual) class is considered abstract in Blink if it has // no public constructors and no create methods. bool RecordInfo::IsConsideredAbstract() { for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin(); it != record_->ctor_end(); ++it) { if (!it->isCopyOrMoveConstructor() && it->getAccess() == AS_public) return false; } for (CXXRecordDecl::method_iterator it = record_->method_begin(); it != record_->method_end(); ++it) { if (it->getNameAsString() == kCreateName) return false; } return true; }
void RecordInfo::DetermineTracingMethods() { if (determined_trace_methods_) return; determined_trace_methods_ = true; if (Config::IsGCBase(name_)) return; CXXMethodDecl* trace = 0; CXXMethodDecl* traceAfterDispatch = 0; bool isTraceAfterDispatch; for (CXXRecordDecl::method_iterator it = record_->method_begin(); it != record_->method_end(); ++it) { if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { if (isTraceAfterDispatch) { traceAfterDispatch = *it; } else { trace = *it; } } else if (it->getNameAsString() == kFinalizeName) { finalize_dispatch_method_ = *it; } } if (traceAfterDispatch) { trace_method_ = traceAfterDispatch; trace_dispatch_method_ = trace; } else { // TODO: Can we never have a dispatch method called trace without the same // class defining a traceAfterDispatch method? trace_method_ = trace; trace_dispatch_method_ = 0; } if (trace_dispatch_method_ && finalize_dispatch_method_) return; // If this class does not define dispatching methods inherit them. for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { // TODO: Does it make sense to inherit multiple dispatch methods? if (CXXMethodDecl* dispatch = it->second.info()->GetTraceDispatchMethod()) { assert(!trace_dispatch_method_ && "Multiple trace dispatching methods"); trace_dispatch_method_ = dispatch; } if (CXXMethodDecl* dispatch = it->second.info()->GetFinalizeDispatchMethod()) { assert(!finalize_dispatch_method_ && "Multiple finalize dispatching methods"); finalize_dispatch_method_ = dispatch; } } }
bool RecordInfo::IsNonNewable() { if (is_non_newable_ == kNotComputed) { bool deleted = false; bool all_deleted = true; for (CXXRecordDecl::method_iterator it = record_->method_begin(); it != record_->method_end(); ++it) { if (it->getNameAsString() == kNewOperatorName) { deleted = it->isDeleted(); all_deleted = all_deleted && deleted; } } is_non_newable_ = (deleted && all_deleted) ? kTrue : kFalse; } return is_non_newable_; }
bool RecordInfo::IsOnlyPlacementNewable() { if (is_only_placement_newable_ == kNotComputed) { bool placement = false; bool new_deleted = false; for (CXXRecordDecl::method_iterator it = record_->method_begin(); it != record_->method_end(); ++it) { if (it->getNameAsString() == kNewOperatorName) { if (it->getNumParams() == 1) { new_deleted = it->isDeleted(); } else if (it->getNumParams() == 2) { placement = !it->isDeleted(); } } } is_only_placement_newable_ = (placement && new_deleted) ? kTrue : kFalse; } return is_only_placement_newable_; }
bool RecordInfo::IsStackAllocated() { if (is_stack_allocated_ == kNotComputed) { is_stack_allocated_ = kFalse; for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { if (it->second.info()->IsStackAllocated()) { is_stack_allocated_ = kTrue; return is_stack_allocated_; } } for (CXXRecordDecl::method_iterator it = record_->method_begin(); it != record_->method_end(); ++it) { if (it->getNameAsString() == kNewOperatorName && it->isDeleted() && Config::IsStackAnnotated(*it)) { is_stack_allocated_ = kTrue; return is_stack_allocated_; } } } return is_stack_allocated_; }