void NewObjectExpression::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { string &cname = isSelf() || isParent() ? m_name : m_origName; bool outsideClass = !isPresent(); if (!m_name.empty() && m_classScope && !m_dynamic) { ClassScopePtr cls = m_classScope; const string& lClassName = cls->getId(); bool skipCreate = cls->canSkipCreateMethod(); if (m_receiverTemp.empty()) { if (outsideClass) { cls->outputVolatileCheckBegin(cg, ar, getScope(), cname); } cg_printf("%s%s(((%s%s*)%s%s())%s", Option::SmartPtrPrefix, lClassName.c_str(), Option::ClassPrefix, lClassName.c_str(), Option::CreateObjectOnlyPrefix, lClassName.c_str(), skipCreate ? "" : "->create("); } else { cg_printf("((%s%s*)%s.get()%s", Option::ClassPrefix, lClassName.c_str(), m_receiverTemp.c_str(), skipCreate ? "" : "->create("); } if (skipCreate) { ASSERT(!m_params || m_params->getOutputCount() == 0); } else { FunctionScope::OutputCPPArguments(m_params, m_funcScope, cg, ar, m_extraArg, m_variableArgument, m_argArrayId, m_argArrayHash, m_argArrayIndex); } if (m_receiverTemp.empty()) { cg_printf(skipCreate ? ")" : "))"); if (outsideClass) { cls->outputVolatileCheckEnd(cg); } } else { if (!skipCreate) cg_printf(")"); if (!isUnused()) { cg_printf(", %s", m_receiverTemp.c_str()); } cg_printf(")"); } } else { bool wrap = false; wrap = m_actualType && m_actualType->is(Type::KindOfVariant) && !m_expectedType && !m_implementedType; if (wrap) { cg_printf("((Variant)"); } cg_printf("id(obj%d)", m_objectTemp); if (wrap) { cg_printf(")"); } } }
bool ClassScope::canSkipCreateMethod(AnalysisResultConstPtr ar) const { // create() is not necessary if // 1) not inheriting from any class // 2) no constructor defined (__construct or class name) // 3) no init() defined if (derivesFromRedeclaring() == Derivation::Redeclaring || getAttribute(HasConstructor) || getAttribute(ClassNameConstructor) || needsInitMethod()) { return false; } if (!m_parent.empty()) { ClassScopePtr parent = getParentScope(ar); if (parent) return parent->canSkipCreateMethod(ar); } return true; }