aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp66
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp8
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp14
-rw-r--r--src/qml/compiler/qv4isel_util_p.h4
-rw-r--r--src/qml/compiler/qv4jsir.cpp343
-rw-r--r--src/qml/compiler/qv4jsir_p.h380
-rw-r--r--src/qml/compiler/qv4ssa.cpp338
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h2
-rw-r--r--src/qml/debugger/qqmldebug.cpp52
-rw-r--r--src/qml/debugger/qqmldebug.h3
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp13
-rw-r--r--src/qml/doc/src/qmltypereference.qdoc2
-rw-r--r--src/qml/jit/qv4regalloc.cpp48
-rw-r--r--src/qml/jsapi/qjsengine.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp30
-rw-r--r--src/qml/jsruntime/qv4engine_p.h29
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp4
-rw-r--r--src/qml/jsruntime/qv4util_p.h127
-rw-r--r--src/qml/jsruntime/qv4value_p.h7
-rw-r--r--src/qml/parser/qqmljsmemorypool_p.h4
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h1
-rw-r--r--src/qml/qml/qqml.h55
-rw-r--r--src/qml/qml/qqmlaccessors_p.h6
-rw-r--r--src/qml/qml/qqmlapplicationengine.h6
-rw-r--r--src/qml/qml/qqmlcomponent.h18
-rw-r--r--src/qml/qml/qqmlcontext.cpp2
-rw-r--r--src/qml/qml/qqmlcontext.h4
-rw-r--r--src/qml/qml/qqmlcontext_p.h1
-rw-r--r--src/qml/qml/qqmlengine.h2
-rw-r--r--src/qml/qml/qqmlengine_p.h2
-rw-r--r--src/qml/qml/qqmlexpression.h6
-rw-r--r--src/qml/qml/qqmlextensionplugin.h2
-rw-r--r--src/qml/qml/qqmlfileselector.h2
-rw-r--r--src/qml/qml/qqmlimport.cpp12
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp2
-rw-r--r--src/qml/qml/qqmllist.h36
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp2
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp1
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h1
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h3
-rw-r--r--src/qml/util/qqmlpropertymap.h2
41 files changed, 864 insertions, 778 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index a34c1cbf0e..1960f1d65b 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1589,7 +1589,9 @@ enum MetaObjectResolverFlags {
static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject);
-static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::MemberExpressionResolver *resolver, QV4::IR::Member *member)
+static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
+ const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
@@ -1600,7 +1602,6 @@ static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::Membe
int value = type->enumValue(qmlEngine, *member->name, &ok);
if (ok) {
member->setEnumValue(value);
- resolver->clear();
return QV4::IR::SInt32Type;
}
}
@@ -1611,25 +1612,30 @@ static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::Membe
tdata->release(); // Decrease the reference count added from QQmlTypeLoader::getType()
// When a singleton tries to reference itself, it may not be complete yet.
if (tdata->isComplete()) {
- initMetaObjectResolver(resolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId));
- resolver->flags |= AllPropertiesAreFinal;
- return resolver->resolveMember(qmlEngine, resolver, member);
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId));
+ newResolver->flags |= AllPropertiesAreFinal;
+ return newResolver->resolveMember(qmlEngine, newResolver, member);
}
} else if (type->isSingleton()) {
const QMetaObject *singletonMeta = type->singletonInstanceInfo()->instanceMetaObject;
if (singletonMeta) { // QJSValue-based singletons cannot be accelerated
- initMetaObjectResolver(resolver, qmlEngine->cache(singletonMeta));
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, qmlEngine->cache(singletonMeta));
member->kind = QV4::IR::Member::MemberOfSingletonObject;
- return resolver->resolveMember(qmlEngine, resolver, member);
+ return newResolver->resolveMember(qmlEngine, newResolver, member);
}
} else if (const QMetaObject *attachedMeta = type->attachedPropertiesType(qmlEngine)) {
QQmlPropertyCache *cache = qmlEngine->cache(attachedMeta);
- initMetaObjectResolver(resolver, cache);
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, cache);
member->setAttachedPropertiesId(type->attachedPropertiesId(qmlEngine));
- return resolver->resolveMember(qmlEngine, resolver, member);
+ return newResolver->resolveMember(qmlEngine, newResolver, member);
}
- resolver->clear();
return result;
}
@@ -1643,7 +1649,9 @@ static void initQmlTypeResolver(QV4::IR::MemberExpressionResolver *resolver, QQm
resolver->flags = 0;
}
-static QV4::IR::Type resolveImportNamespace(QQmlEnginePrivate *, QV4::IR::MemberExpressionResolver *resolver, QV4::IR::Member *member)
+static QV4::IR::DiscoveredType resolveImportNamespace(
+ QQmlEnginePrivate *, const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
QQmlTypeNameCache *typeNamespace = static_cast<QQmlTypeNameCache*>(resolver->extraData);
@@ -1660,19 +1668,21 @@ static QV4::IR::Type resolveImportNamespace(QQmlEnginePrivate *, QV4::IR::Member
// through the singleton getter in the run-time. Until then we
// can't accelerate access :(
if (!r.type->isSingleton()) {
- initQmlTypeResolver(resolver, r.type);
- return QV4::IR::QObjectType;
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initQmlTypeResolver(newResolver, r.type);
+ return QV4::IR::DiscoveredType(newResolver);
}
} else {
Q_ASSERT(false); // How can this happen?
}
}
- resolver->clear();
return result;
}
-static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlTypeNameCache *imports, const void *importNamespace)
+static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resolver,
+ QQmlTypeNameCache *imports, const void *importNamespace)
{
resolver->resolveMember = &resolveImportNamespace;
resolver->data = const_cast<void*>(importNamespace);
@@ -1680,7 +1690,9 @@ static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resol
resolver->flags = 0;
}
-static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4::IR::MemberExpressionResolver *resolver, QV4::IR::Member *member)
+static QV4::IR::DiscoveredType resolveMetaObjectProperty(
+ QQmlEnginePrivate *qmlEngine, const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
QQmlPropertyCache *metaObject = static_cast<QQmlPropertyCache*>(resolver->data);
@@ -1694,7 +1706,6 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4
int value = metaEnum.keyToValue(enumName.constData(), &ok);
if (ok) {
member->setEnumValue(value);
- resolver->clear();
return QV4::IR::SInt32Type;
}
}
@@ -1739,21 +1750,25 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4
default:
if (property->isQObject()) {
if (QQmlPropertyCache *cache = qmlEngine->propertyCacheForType(property->propType)) {
- initMetaObjectResolver(resolver, cache);
- return QV4::IR::QObjectType;
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, cache);
+ return QV4::IR::DiscoveredType(newResolver);
}
} else if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType)) {
if (QQmlPropertyCache *cache = qmlEngine->cache(valueTypeMetaObject)) {
- initMetaObjectResolver(resolver, cache);
- resolver->flags |= ResolveTypeInformationOnly;
- return QV4::IR::QObjectType;
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, cache);
+ newResolver->flags |= ResolveTypeInformationOnly;
+ return QV4::IR::DiscoveredType(newResolver);
}
}
break;
}
}
}
- resolver->clear();
+
return result;
}
@@ -1809,6 +1824,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
result = _block->TEMP(result->index);
if (mapping.type) {
result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ result->memberResolver->owner = _function;
initMetaObjectResolver(result->memberResolver, mapping.type);
result->memberResolver->flags |= AllPropertiesAreFinal;
}
@@ -1831,6 +1847,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
result = _block->TEMP(result->index);
result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ result->memberResolver->owner = _function;
initQmlTypeResolver(result->memberResolver, r.type);
return result;
} else {
@@ -1839,6 +1856,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
namespaceName->freeOfSideEffects = true;
QV4::IR::Temp *result = _block->TEMP(_block->newTemp());
result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ result->memberResolver->owner = _function;
initImportNamespaceResolver(result->memberResolver, imports, r.importNamespace);
_block->MOVE(result, namespaceName);
@@ -1855,6 +1873,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
if (pd) {
QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ base->memberResolver->owner = _function;
initMetaObjectResolver(base->memberResolver, _scopeObject);
return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlScopeObject);
}
@@ -1868,6 +1887,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
if (pd) {
QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ base->memberResolver->owner = _function;
initMetaObjectResolver(base->memberResolver, _contextObject);
return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlContextObject);
}
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 33716d57b8..a71793f2b6 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -2731,8 +2731,8 @@ bool QQmlJavaScriptBindingExpressionSimplificationPass::simplifyBinding(QV4::IR:
if (function->basicBlockCount() > 10)
return false;
- foreach (QV4::IR::BasicBlock *bb, function->basicBlocks()) {
- foreach (QV4::IR::Stmt *s, bb->statements()) {
+ for (QV4::IR::BasicBlock *bb : function->basicBlocks()) {
+ for (QV4::IR::Stmt *s : bb->statements()) {
s->accept(this);
if (!_canSimplify)
return false;
@@ -2901,8 +2901,8 @@ void QQmlIRFunctionCleanser::clean()
module->functions = newFunctions;
foreach (QV4::IR::Function *function, module->functions) {
- foreach (QV4::IR::BasicBlock *block, function->basicBlocks()) {
- foreach (QV4::IR::Stmt *s, block->statements()) {
+ for (QV4::IR::BasicBlock *block : function->basicBlocks()) {
+ for (QV4::IR::Stmt *s : block->statements()) {
s->accept(this);
}
}
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index b3468848ca..be10d50e9b 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -255,16 +255,16 @@ protected:
if (IR::Jump *jump = s->asJump()) {
IR::MoveMapping moves;
- foreach (IR::Stmt *succStmt, jump->target->statements()) {
+ for (IR::Stmt *succStmt : jump->target->statements()) {
if (IR::Phi *phi = succStmt->asPhi()) {
forceActivation(*phi->targetTemp);
- for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) {
- IR::Expr *e = phi->d->incoming[i];
+ for (int i = 0, ei = phi->incoming.size(); i != ei; ++i) {
+ IR::Expr *e = phi->incoming[i];
if (IR::Temp *t = e->asTemp()) {
forceActivation(*t);
}
if (jump->target->in[i] == _currentBasicBlock)
- moves.add(phi->d->incoming[i], phi->targetTemp);
+ moves.add(phi->incoming[i], phi->targetTemp);
}
} else {
break;
@@ -303,7 +303,7 @@ protected:
#if !defined(QT_NO_DEBUG)
Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index));
Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]);
- foreach (IR::Expr *e, phi->d->incoming) {
+ foreach (IR::Expr *e, phi->incoming) {
if (IR::Temp *t = e->asTemp())
Q_ASSERT(_stackSlotForTemp.contains(t->index));
}
@@ -385,7 +385,7 @@ void InstructionSelection::run(int functionIndex)
addInstruction(push);
currentLine = 0;
- QVector<IR::BasicBlock *> basicBlocks = _function->basicBlocks();
+ const QVector<IR::BasicBlock *> &basicBlocks = _function->basicBlocks();
for (int i = 0, ei = basicBlocks.size(); i != ei; ++i) {
blockNeedsDebugInstruction = irModule->debugMode;
_block = basicBlocks[i];
@@ -404,7 +404,7 @@ void InstructionSelection::run(int functionIndex)
exceptionHandler = _block->catchBlock;
}
- foreach (IR::Stmt *s, _block->statements()) {
+ for (IR::Stmt *s : _block->statements()) {
_currentStatement = s;
if (s->location.isValid()) {
diff --git a/src/qml/compiler/qv4isel_util_p.h b/src/qml/compiler/qv4isel_util_p.h
index 9ef3ef6721..674fc01623 100644
--- a/src/qml/compiler/qv4isel_util_p.h
+++ b/src/qml/compiler/qv4isel_util_p.h
@@ -145,11 +145,11 @@ public:
{
_stackSlotForTemp.reserve(function->tempCount);
- foreach (IR::BasicBlock *bb, function->basicBlocks()) {
+ for (IR::BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
_currentBasicBlock = bb;
- foreach (IR::Stmt *s, bb->statements())
+ for (IR::Stmt *s : bb->statements())
process(s);
}
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 4c87b7557e..b28db59190 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -511,344 +511,23 @@ void Function::setStatementCount(int cnt)
_statementCount = cnt;
}
-BasicBlock::~BasicBlock()
-{
- for (Stmt *s : qAsConst(_statements)) {
- Phi *p = s->asPhi();
- if (p)
- p->destroyData();
- }
-}
-
-unsigned BasicBlock::newTemp()
-{
- Q_ASSERT(!isRemoved());
- return function->tempCount++;
-}
-
-Temp *BasicBlock::TEMP(unsigned index)
-{
- Q_ASSERT(!isRemoved());
- Temp *e = function->New<Temp>();
- e->init(Temp::VirtualRegister, index);
- return e;
-}
-
-ArgLocal *BasicBlock::ARG(unsigned index, unsigned scope)
-{
- Q_ASSERT(!isRemoved());
- ArgLocal *e = function->New<ArgLocal>();
- e->init(scope ? ArgLocal::ScopedFormal : ArgLocal::Formal, index, scope);
- return e;
-}
-
-ArgLocal *BasicBlock::LOCAL(unsigned index, unsigned scope)
-{
- Q_ASSERT(!isRemoved());
- ArgLocal *e = function->New<ArgLocal>();
- e->init(scope ? ArgLocal::ScopedLocal : ArgLocal::Local, index, scope);
- return e;
-}
-
-Expr *BasicBlock::CONST(Type type, double value)
-{
- Q_ASSERT(!isRemoved());
- Const *e = function->New<Const>();
- if (type == NumberType) {
- int ival = (int)value;
- // +0 != -0, so we need to convert to double when negating 0
- if (ival == value && !(value == 0 && isNegative(value)))
- type = SInt32Type;
- else
- type = DoubleType;
- } else if (type == NullType) {
- value = 0;
- } else if (type == UndefinedType) {
- value = qQNaN();
- }
-
- e->init(type, value);
- return e;
-}
-
-Expr *BasicBlock::STRING(const QString *value)
-{
- Q_ASSERT(!isRemoved());
- String *e = function->New<String>();
- e->init(value);
- return e;
-}
-
-Expr *BasicBlock::REGEXP(const QString *value, int flags)
-{
- Q_ASSERT(!isRemoved());
- RegExp *e = function->New<RegExp>();
- e->init(value, flags);
- return e;
-}
-
-Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
-{
- Q_ASSERT(!isRemoved());
- Name *e = function->New<Name>();
- e->init(function->newString(id), line, column);
- return e;
-}
-
-Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column)
-{
- Q_ASSERT(!isRemoved());
- Name *e = function->New<Name>();
- e->initGlobal(function->newString(id), line, column);
- return e;
-}
-
-
-Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column)
-{
- Q_ASSERT(!isRemoved());
- Name *e = function->New<Name>();
- e->init(builtin, line, column);
- return e;
-}
-
-Closure *BasicBlock::CLOSURE(int functionInModule)
-{
- Q_ASSERT(!isRemoved());
- Closure *clos = function->New<Closure>();
- clos->init(functionInModule, function->module->functions.at(functionInModule)->name);
- return clos;
-}
-
-Expr *BasicBlock::CONVERT(Expr *expr, Type type)
-{
- Q_ASSERT(!isRemoved());
- Convert *e = function->New<Convert>();
- e->init(expr, type);
- return e;
-}
-
-Expr *BasicBlock::UNOP(AluOp op, Expr *expr)
-{
- Q_ASSERT(!isRemoved());
- Unop *e = function->New<Unop>();
- e->init(op, expr);
- return e;
-}
-
-Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
-{
- Q_ASSERT(!isRemoved());
- Binop *e = function->New<Binop>();
- e->init(op, left, right);
- return e;
-}
-
-Expr *BasicBlock::CALL(Expr *base, ExprList *args)
-{
- Q_ASSERT(!isRemoved());
- Call *e = function->New<Call>();
- e->init(base, args);
- int argc = 0;
- for (ExprList *it = args; it; it = it->next)
- ++argc;
- function->maxNumberOfArguments = qMax(function->maxNumberOfArguments, argc);
- return e;
-}
-
-Expr *BasicBlock::NEW(Expr *base, ExprList *args)
-{
- Q_ASSERT(!isRemoved());
- New *e = function->New<New>();
- e->init(base, args);
- return e;
-}
-
-Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index)
-{
- Q_ASSERT(!isRemoved());
- Subscript *e = function->New<Subscript>();
- e->init(base, index);
- return e;
-}
-
-Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *property, uchar kind, int attachedPropertiesIdOrEnumValue)
-{
- Q_ASSERT(!isRemoved());
- Member*e = function->New<Member>();
- e->init(base, name, property, kind, attachedPropertiesIdOrEnumValue);
- return e;
-}
-
-Stmt *BasicBlock::EXP(Expr *expr)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Exp *s = function->NewStmt<Exp>();
- s->init(expr);
- appendStatement(s);
- return s;
-}
-
-Stmt *BasicBlock::MOVE(Expr *target, Expr *source)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Move *s = function->NewStmt<Move>();
- s->init(target, source);
- appendStatement(s);
- return s;
-}
-
-Stmt *BasicBlock::JUMP(BasicBlock *target)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Jump *s = function->NewStmt<Jump>();
- s->init(target);
- appendStatement(s);
-
- Q_ASSERT(! out.contains(target));
- out.append(target);
-
- Q_ASSERT(! target->in.contains(this));
- target->in.append(this);
-
- return s;
-}
-
-Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- if (iftrue == iffalse) {
- MOVE(TEMP(newTemp()), cond);
- return JUMP(iftrue);
- }
-
- CJump *s = function->NewStmt<CJump>();
- s->init(cond, iftrue, iffalse, this);
- appendStatement(s);
-
- Q_ASSERT(! out.contains(iftrue));
- out.append(iftrue);
-
- Q_ASSERT(! iftrue->in.contains(this));
- iftrue->in.append(this);
-
- Q_ASSERT(! out.contains(iffalse));
- out.append(iffalse);
-
- Q_ASSERT(! iffalse->in.contains(this));
- iffalse->in.append(this);
-
- return s;
-}
-
-Stmt *BasicBlock::RET(Expr *expr)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Ret *s = function->NewStmt<Ret>();
- s->init(expr);
- appendStatement(s);
- return s;
-}
-
void BasicBlock::setStatements(const QVector<Stmt *> &newStatements)
{
Q_ASSERT(!isRemoved());
Q_ASSERT(newStatements.size() >= _statements.size());
- // FIXME: this gets quite inefficient for large basic-blocks, so this function/case should be re-worked.
for (Stmt *s : qAsConst(_statements)) {
- Phi *p = s->asPhi();
- if (!p)
- continue;
-
- if (!newStatements.contains(p))
- p->destroyData();
+ if (Phi *p = s->asPhi()) {
+ if (!newStatements.contains(p)) {
+ // phi-node was not copied over, so:
+ p->destroyData();
+ }
+ } else {
+ break;
+ }
}
_statements = newStatements;
}
-void BasicBlock::appendStatement(Stmt *statement)
-{
- Q_ASSERT(!isRemoved());
- if (nextLocation.startLine)
- statement->location = nextLocation;
- _statements.append(statement);
-}
-
-void BasicBlock::prependStatement(Stmt *stmt)
-{
- Q_ASSERT(!isRemoved());
- _statements.prepend(stmt);
-}
-
-void BasicBlock::prependStatements(const QVector<Stmt *> &stmts)
-{
- Q_ASSERT(!isRemoved());
- QVector<Stmt *> newStmts = stmts;
- newStmts += _statements;
- _statements = newStmts;
-}
-
-void BasicBlock::insertStatementBefore(Stmt *before, Stmt *newStmt)
-{
- int idx = _statements.indexOf(before);
- Q_ASSERT(idx >= 0);
- _statements.insert(idx, newStmt);
-}
-
-void BasicBlock::insertStatementBefore(int index, Stmt *newStmt)
-{
- Q_ASSERT(index >= 0);
- _statements.insert(index, newStmt);
-}
-
-void BasicBlock::insertStatementBeforeTerminator(Stmt *stmt)
-{
- Q_ASSERT(!isRemoved());
- _statements.insert(_statements.size() - 1, stmt);
-}
-
-void BasicBlock::replaceStatement(int index, Stmt *newStmt)
-{
- Q_ASSERT(!isRemoved());
- Phi *p = _statements[index]->asPhi();
- if (p)
- p->destroyData();
- _statements[index] = newStmt;
-}
-
-void BasicBlock::removeStatement(Stmt *stmt)
-{
- Q_ASSERT(!isRemoved());
- Phi *p = stmt->asPhi();
- if (p)
- p->destroyData();
- _statements.remove(_statements.indexOf(stmt));
-}
-
-void BasicBlock::removeStatement(int idx)
-{
- Q_ASSERT(!isRemoved());
- Phi *p = _statements[idx]->asPhi();
- if (p)
- p->destroyData();
- _statements.remove(idx);
-}
-
CloneExpr::CloneExpr(BasicBlock *block)
: block(block), cloned(0)
{
@@ -1084,13 +763,13 @@ void IRPrinter::visitPhi(Phi *s)
s->targetTemp->accept(this);
*out << " = phi ";
- for (int i = 0, ei = s->d->incoming.size(); i < ei; ++i) {
+ for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
if (i > 0)
*out << ", ";
if (currentBB)
*out << 'L' << currentBB->in.at(i)->index() << ": ";
- if (s->d->incoming[i])
- s->d->incoming[i]->accept(this);
+ if (s->incoming[i])
+ s->incoming[i]->accept(this);
}
}
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 974e8dfe0d..eafecae494 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -244,13 +244,37 @@ struct StmtVisitor {
virtual void visitPhi(Phi *) = 0;
};
+struct MemberExpressionResolver;
+
+struct DiscoveredType {
+ int type;
+ MemberExpressionResolver *memberResolver;
+
+ DiscoveredType() : type(UnknownType), memberResolver(0) {}
+ DiscoveredType(Type t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
+ explicit DiscoveredType(int t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
+ explicit DiscoveredType(MemberExpressionResolver *memberResolver)
+ : type(QObjectType)
+ , memberResolver(memberResolver)
+ { Q_ASSERT(memberResolver); }
+
+ bool test(Type t) const { return type & t; }
+ bool isNumber() const { return (type & NumberType) && !(type & ~NumberType); }
+
+ bool operator!=(Type other) const { return type != other; }
+ bool operator==(Type other) const { return type == other; }
+ bool operator==(const DiscoveredType &other) const { return type == other.type; }
+ bool operator!=(const DiscoveredType &other) const { return type != other.type; }
+};
struct MemberExpressionResolver
{
- typedef Type (*ResolveFunction)(QQmlEnginePrivate *engine, MemberExpressionResolver *resolver, Member *member);
+ typedef DiscoveredType (*ResolveFunction)(QQmlEnginePrivate *engine,
+ const MemberExpressionResolver *resolver,
+ Member *member);
MemberExpressionResolver()
- : resolveMember(0), data(0), extraData(0), flags(0) {}
+ : resolveMember(0), data(0), extraData(0), owner(nullptr), flags(0) {}
bool isValid() const { return !!resolveMember; }
void clear() { *this = MemberExpressionResolver(); }
@@ -258,6 +282,7 @@ struct MemberExpressionResolver
ResolveFunction resolveMember;
void *data; // Could be pointer to meta object, importNameSpace, etc. - depends on resolveMember implementation
void *extraData; // Could be QQmlTypeNameCache
+ Function *owner;
unsigned int flags;
};
@@ -751,23 +776,21 @@ struct Ret: Stmt {
virtual Ret *asRet() { return this; }
};
+// Phi nodes can only occur at the start of a basic block. If there are any, they need to be
+// subsequent to eachother, and the first phi node should be the first statement in the basic-block.
+// A number of loops rely on this behavior, so they don't need to walk through the whole list
+// of instructions in a basic-block (e.g. the calls to destroyData in BasicBlock::~BasicBlock).
struct Phi: Stmt {
Temp *targetTemp;
- struct Data {
- QVector<Expr *> incoming; // used by Phi nodes
- };
+ VarLengthArray<Expr *, 4> incoming;
- Data *d;
-
- Phi(int id): Stmt(id), d(0) {}
+ Phi(int id): Stmt(id) {}
virtual void accept(StmtVisitor *v) { v->visitPhi(this); }
virtual Phi *asPhi() { return this; }
- void destroyData() {
- delete d;
- d = 0;
- }
+ void destroyData()
+ { incoming.~VarLengthArray(); }
};
struct Q_QML_PRIVATE_EXPORT Module {
@@ -813,7 +836,17 @@ public:
, _groupStart(false)
, _isRemoved(false)
{}
- ~BasicBlock();
+
+ ~BasicBlock()
+ {
+ for (Stmt *s : qAsConst(_statements)) {
+ if (Phi *p = s->asPhi()) {
+ p->destroyData();
+ } else {
+ break;
+ }
+ }
+ }
const QVector<Stmt *> &statements() const
{
@@ -836,15 +869,73 @@ public:
return i;
}
- void appendStatement(Stmt *statement);
- void prependStatement(Stmt *stmt);
- void prependStatements(const QVector<Stmt *> &stmts);
- void insertStatementBefore(Stmt *before, Stmt *newStmt);
- void insertStatementBefore(int index, Stmt *newStmt);
- void insertStatementBeforeTerminator(Stmt *stmt);
- void replaceStatement(int index, Stmt *newStmt);
- void removeStatement(Stmt *stmt);
- void removeStatement(int idx);
+ void appendStatement(Stmt *statement)
+ {
+ Q_ASSERT(!isRemoved());
+ if (nextLocation.startLine)
+ statement->location = nextLocation;
+ _statements.append(statement);
+ }
+
+ void prependStatement(Stmt *stmt)
+ {
+ Q_ASSERT(!isRemoved());
+ _statements.prepend(stmt);
+ }
+
+ void prependStatements(const QVector<Stmt *> &stmts)
+ {
+ Q_ASSERT(!isRemoved());
+ QVector<Stmt *> newStmts = stmts;
+ newStmts += _statements;
+ _statements = newStmts;
+ }
+
+ void insertStatementBefore(Stmt *before, Stmt *newStmt)
+ {
+ int idx = _statements.indexOf(before);
+ Q_ASSERT(idx >= 0);
+ _statements.insert(idx, newStmt);
+ }
+
+ void insertStatementBefore(int index, Stmt *newStmt)
+ {
+ Q_ASSERT(index >= 0);
+ _statements.insert(index, newStmt);
+ }
+
+ void insertStatementBeforeTerminator(Stmt *stmt)
+ {
+ Q_ASSERT(!isRemoved());
+ _statements.insert(_statements.size() - 1, stmt);
+ }
+
+ void replaceStatement(int index, Stmt *newStmt)
+ {
+ Q_ASSERT(!isRemoved());
+ if (Phi *p = _statements[index]->asPhi()) {
+ p->destroyData();
+ }
+ _statements[index] = newStmt;
+ }
+
+ void removeStatement(Stmt *stmt)
+ {
+ Q_ASSERT(!isRemoved());
+ if (Phi *p = stmt->asPhi()) {
+ p->destroyData();
+ }
+ _statements.remove(_statements.indexOf(stmt));
+ }
+
+ void removeStatement(int idx)
+ {
+ Q_ASSERT(!isRemoved());
+ if (Phi *p = _statements[idx]->asPhi()) {
+ p->destroyData();
+ }
+ _statements.remove(idx);
+ }
inline bool isEmpty() const {
Q_ASSERT(!isRemoved());
@@ -1209,6 +1300,251 @@ protected:
BasicBlock *currentBB;
};
+inline unsigned BasicBlock::newTemp()
+{
+ Q_ASSERT(!isRemoved());
+ return function->tempCount++;
+}
+
+inline Temp *BasicBlock::TEMP(unsigned index)
+{
+ Q_ASSERT(!isRemoved());
+ Temp *e = function->New<Temp>();
+ e->init(Temp::VirtualRegister, index);
+ return e;
+}
+
+inline ArgLocal *BasicBlock::ARG(unsigned index, unsigned scope)
+{
+ Q_ASSERT(!isRemoved());
+ ArgLocal *e = function->New<ArgLocal>();
+ e->init(scope ? ArgLocal::ScopedFormal : ArgLocal::Formal, index, scope);
+ return e;
+}
+
+inline ArgLocal *BasicBlock::LOCAL(unsigned index, unsigned scope)
+{
+ Q_ASSERT(!isRemoved());
+ ArgLocal *e = function->New<ArgLocal>();
+ e->init(scope ? ArgLocal::ScopedLocal : ArgLocal::Local, index, scope);
+ return e;
+}
+
+inline Expr *BasicBlock::CONST(Type type, double value)
+{
+ Q_ASSERT(!isRemoved());
+ Const *e = function->New<Const>();
+ if (type == NumberType) {
+ int ival = (int)value;
+ // +0 != -0, so we need to convert to double when negating 0
+ if (ival == value && !(value == 0 && isNegative(value)))
+ type = SInt32Type;
+ else
+ type = DoubleType;
+ } else if (type == NullType) {
+ value = 0;
+ } else if (type == UndefinedType) {
+ value = qQNaN();
+ }
+
+ e->init(type, value);
+ return e;
+}
+
+inline Expr *BasicBlock::STRING(const QString *value)
+{
+ Q_ASSERT(!isRemoved());
+ String *e = function->New<String>();
+ e->init(value);
+ return e;
+}
+
+inline Expr *BasicBlock::REGEXP(const QString *value, int flags)
+{
+ Q_ASSERT(!isRemoved());
+ RegExp *e = function->New<RegExp>();
+ e->init(value, flags);
+ return e;
+}
+
+inline Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
+{
+ Q_ASSERT(!isRemoved());
+ Name *e = function->New<Name>();
+ e->init(function->newString(id), line, column);
+ return e;
+}
+
+inline Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column)
+{
+ Q_ASSERT(!isRemoved());
+ Name *e = function->New<Name>();
+ e->initGlobal(function->newString(id), line, column);
+ return e;
+}
+
+
+inline Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column)
+{
+ Q_ASSERT(!isRemoved());
+ Name *e = function->New<Name>();
+ e->init(builtin, line, column);
+ return e;
+}
+
+inline Closure *BasicBlock::CLOSURE(int functionInModule)
+{
+ Q_ASSERT(!isRemoved());
+ Closure *clos = function->New<Closure>();
+ clos->init(functionInModule, function->module->functions.at(functionInModule)->name);
+ return clos;
+}
+
+inline Expr *BasicBlock::CONVERT(Expr *expr, Type type)
+{
+ Q_ASSERT(!isRemoved());
+ Convert *e = function->New<Convert>();
+ e->init(expr, type);
+ return e;
+}
+
+inline Expr *BasicBlock::UNOP(AluOp op, Expr *expr)
+{
+ Q_ASSERT(!isRemoved());
+ Unop *e = function->New<Unop>();
+ e->init(op, expr);
+ return e;
+}
+
+inline Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
+{
+ Q_ASSERT(!isRemoved());
+ Binop *e = function->New<Binop>();
+ e->init(op, left, right);
+ return e;
+}
+
+inline Expr *BasicBlock::CALL(Expr *base, ExprList *args)
+{
+ Q_ASSERT(!isRemoved());
+ Call *e = function->New<Call>();
+ e->init(base, args);
+ int argc = 0;
+ for (ExprList *it = args; it; it = it->next)
+ ++argc;
+ function->maxNumberOfArguments = qMax(function->maxNumberOfArguments, argc);
+ return e;
+}
+
+inline Expr *BasicBlock::NEW(Expr *base, ExprList *args)
+{
+ Q_ASSERT(!isRemoved());
+ New *e = function->New<New>();
+ e->init(base, args);
+ return e;
+}
+
+inline Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index)
+{
+ Q_ASSERT(!isRemoved());
+ Subscript *e = function->New<Subscript>();
+ e->init(base, index);
+ return e;
+}
+
+inline Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *property, uchar kind, int attachedPropertiesIdOrEnumValue)
+{
+ Q_ASSERT(!isRemoved());
+ Member*e = function->New<Member>();
+ e->init(base, name, property, kind, attachedPropertiesIdOrEnumValue);
+ return e;
+}
+
+inline Stmt *BasicBlock::EXP(Expr *expr)
+{
+ Q_ASSERT(!isRemoved());
+ if (isTerminated())
+ return 0;
+
+ Exp *s = function->NewStmt<Exp>();
+ s->init(expr);
+ appendStatement(s);
+ return s;
+}
+
+inline Stmt *BasicBlock::MOVE(Expr *target, Expr *source)
+{
+ Q_ASSERT(!isRemoved());
+ if (isTerminated())
+ return 0;
+
+ Move *s = function->NewStmt<Move>();
+ s->init(target, source);
+ appendStatement(s);
+ return s;
+}
+
+inline Stmt *BasicBlock::JUMP(BasicBlock *target)
+{
+ Q_ASSERT(!isRemoved());
+ if (isTerminated())
+ return 0;
+
+ Jump *s = function->NewStmt<Jump>();
+ s->init(target);
+ appendStatement(s);
+
+ Q_ASSERT(! out.contains(target));
+ out.append(target);
+
+ Q_ASSERT(! target->in.contains(this));
+ target->in.append(this);
+
+ return s;
+}
+
+inline Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
+{
+ Q_ASSERT(!isRemoved());
+ if (isTerminated())
+ return 0;
+
+ if (iftrue == iffalse) {
+ MOVE(TEMP(newTemp()), cond);
+ return JUMP(iftrue);
+ }
+
+ CJump *s = function->NewStmt<CJump>();
+ s->init(cond, iftrue, iffalse, this);
+ appendStatement(s);
+
+ Q_ASSERT(! out.contains(iftrue));
+ out.append(iftrue);
+
+ Q_ASSERT(! iftrue->in.contains(this));
+ iftrue->in.append(this);
+
+ Q_ASSERT(! out.contains(iffalse));
+ out.append(iffalse);
+
+ Q_ASSERT(! iffalse->in.contains(this));
+ iffalse->in.append(this);
+
+ return s;
+}
+
+inline Stmt *BasicBlock::RET(Expr *expr)
+{
+ Q_ASSERT(!isRemoved());
+ if (isTerminated())
+ return 0;
+
+ Ret *s = function->NewStmt<Ret>();
+ s->init(expr);
+ appendStatement(s);
+ return s;
+}
+
} // end of namespace IR
} // end of namespace QV4
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 7881ab951a..6a4c1c54d6 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -56,7 +56,6 @@
#include <cmath>
#include <iostream>
#include <cassert>
-#include <algorithm>
QT_USE_NAMESPACE
@@ -87,120 +86,6 @@ static void showMeTheCode(IR::Function *function, const char *marker)
}
}
-#if !defined(BROKEN_STD_VECTOR_BOOL_OR_BROKEN_STD_FIND)
-// Sanity:
-class BitVector
-{
- std::vector<bool> bits;
-
-public:
- BitVector(int size = 0, bool value = false)
- : bits(size, value)
- {}
-
- void reserve(int size)
- { bits.reserve(size); }
-
- int size() const
- {
- Q_ASSERT(bits.size() < INT_MAX);
- return static_cast<int>(bits.size());
- }
-
- void resize(int newSize)
- { bits.resize(newSize); }
-
- void assign(int newSize, bool value)
- { bits.assign(newSize, value); }
-
- int findNext(int start, bool value, bool wrapAround) const
- {
- // The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an
- // iterator pointing to the last element. It will not be set to ::end(), but beyond
- // that. (It will be set to the first multiple of the native word size that is bigger
- // than size().)
- //
- // See http://llvm.org/bugs/show_bug.cgi?id=19663
- //
- // The work-around is to calculate the distance, and compare it to the size() to see if it's
- // beyond the end, or take the minimum of the distance and the size.
-
- size_t pos = std::distance(bits.begin(),
- std::find(bits.begin() + start, bits.end(), value));
- if (wrapAround && pos >= static_cast<size_t>(size()))
- pos = std::distance(bits.begin(),
- std::find(bits.begin(), bits.begin() + start, value));
-
- pos = qMin(pos, static_cast<size_t>(size()));
-
- Q_ASSERT(pos <= static_cast<size_t>(size()));
- Q_ASSERT(pos < INT_MAX);
-
- return static_cast<int>(pos);
- }
-
- bool at(int idx) const
- { return bits.at(idx); }
-
- void setBit(int idx)
- { bits[idx] = true; }
-
- void clearBit(int idx)
- { bits[idx] = false; }
-};
-#else // Insanity:
-class BitVector
-{
- QBitArray bits;
-
-public:
- BitVector(int size = 0, bool value = false)
- : bits(size, value)
- {}
-
- void reserve(int size)
- { Q_UNUSED(size); }
-
- int size() const
- { return bits.size(); }
-
- void resize(int newSize)
- { bits.resize(newSize); }
-
- void assign(int newSize, bool value)
- {
- bits.resize(newSize);
- bits.fill(value);
- }
-
- int findNext(int start, bool value, bool wrapAround) const
- {
- for (int i = start, ei = size(); i < ei; ++i) {
- if (at(i) == value)
- return i;
- }
-
- if (wrapAround) {
- for (int i = 0, ei = start; i < ei; ++i) {
- if (at(i) == value)
- return i;
- }
- }
-
- return size();
- }
-
- bool at(int idx) const
- { return bits.at(idx); }
-
- void setBit(int idx)
- { bits[idx] = true; }
-
- void clearBit(int idx)
- { bits[idx] = false; }
-};
-#endif
-
class ProcessedBlocks
{
BitVector processed;
@@ -557,7 +442,7 @@ class DominatorTree
BasicBlockIndex p = d->parent[n];
BasicBlockIndex s = p;
- foreach (BasicBlock *v, function->basicBlock(n)->in) {
+ for (BasicBlock *v : function->basicBlock(n)->in) {
BasicBlockIndex ss = InvalidBasicBlockIndex;
if (d->dfnum[v->index()] <= d->dfnum[n])
ss = v->index();
@@ -617,7 +502,7 @@ public:
// compute children of each node in the dominator tree
std::vector<std::vector<BasicBlockIndex> > children; // BasicBlock index -> children
children.resize(function->basicBlockCount());
- foreach (BasicBlock *n, function->basicBlocks()) {
+ for (BasicBlock *n : function->basicBlocks()) {
if (n->isRemoved())
continue;
const BasicBlockIndex nodeIndex = n->index();
@@ -633,7 +518,7 @@ public:
nodeStatus.resize(function->basicBlockCount());
std::vector<BasicBlockIndex> worklist;
worklist.reserve(function->basicBlockCount());
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
BasicBlockIndex nodeIndex = bb->index();
@@ -667,7 +552,7 @@ public:
if (np.todo.empty()) {
BasicBlockSet &S = DF[node];
S.init(function);
- foreach (BasicBlock *y, function->basicBlock(node)->out)
+ for (BasicBlock *y : function->basicBlock(node)->out)
if (idom[y->index()] != node)
S.insert(y);
for (BasicBlockIndex child : np.children) {
@@ -689,7 +574,7 @@ public:
buf.open(QIODevice::WriteOnly);
QTextStream qout(&buf);
qout << "Dominator Frontiers:" << endl;
- foreach (BasicBlock *n, function->basicBlocks()) {
+ for (BasicBlock *n : function->basicBlocks()) {
if (n->isRemoved())
continue;
@@ -706,7 +591,7 @@ public:
}
if (DebugDominatorFrontiers && DebugCodeCanUseLotsOfCpu) {
- foreach (BasicBlock *n, function->basicBlocks()) {
+ for (BasicBlock *n : function->basicBlocks()) {
if (n->isRemoved())
continue;
const BasicBlockSet &fBlocks = DF[n->index()];
@@ -714,7 +599,7 @@ public:
BasicBlock *fBlock = *it;
Q_ASSERT(!dominates(n, fBlock) || fBlock == n);
bool hasDominatedSucc = false;
- foreach (BasicBlock *succ, fBlock->in) {
+ for (BasicBlock *succ : fBlock->in) {
if (dominates(n, succ)) {
hasDominatedSucc = true;
break;
@@ -747,7 +632,7 @@ public:
buf.open(QIODevice::WriteOnly);
QTextStream qout(&buf);
qout << "Immediate dominators:" << endl;
- foreach (BasicBlock *to, function->basicBlocks()) {
+ for (BasicBlock *to : function->basicBlocks()) {
if (to->isRemoved())
continue;
@@ -881,7 +766,7 @@ private:
{
std::vector<int> nodeDepths(size_t(function->basicBlockCount()), -1);
nodeDepths[0] = 0;
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
@@ -945,8 +830,7 @@ private:
std::vector<BasicBlockIndex> prefix;
prefix.reserve(32);
- for (int i = 0, ei = node->in.size(); i != ei; ++i) {
- BasicBlock *in = node->in.at(i);
+ for (BasicBlock *in : node->in) {
if (node == in) // back-edge to self
continue;
if (dominates(node->index(), in->index())) // a known back-edge
@@ -1055,13 +939,13 @@ public:
for (size_t i = 0; i != ei; ++i)
A_orig[i].reserve(8);
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
currentBB = bb;
killed.assign(function->tempCount, false);
- foreach (Stmt *s, bb->statements())
+ for (Stmt *s : bb->statements())
s->accept(this);
}
}
@@ -1381,16 +1265,15 @@ public:
void insertPhiNode(const Temp &a, BasicBlock *y, IR::Function *f) {
Phi *phiNode = f->NewStmt<Phi>();
- phiNode->d = new Phi::Data;
phiNode->targetTemp = f->New<Temp>();
phiNode->targetTemp->init(a.kind, a.index);
y->prependStatement(phiNode);
- phiNode->d->incoming.resize(y->in.size());
+ phiNode->incoming.resize(y->in.size());
for (int i = 0, ei = y->in.size(); i < ei; ++i) {
Temp *t = f->New<Temp>();
t->init(a.kind, a.index);
- phiNode->d->incoming[i] = t;
+ phiNode->incoming[i] = t;
}
}
@@ -1565,7 +1448,7 @@ private:
processed.markAsProcessed(bb);
BasicBlock *next = 0;
- foreach (BasicBlock *out, bb->out) {
+ for (BasicBlock *out : bb->out) {
if (processed.alreadyProcessed(out))
continue;
if (!next)
@@ -1581,17 +1464,17 @@ private:
{
currentBB = bb;
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
currentStmt = s;
s->accept(this);
}
- foreach (BasicBlock *Y, bb->out) {
+ for (BasicBlock *Y : bb->out) {
const int j = Y->in.indexOf(bb);
Q_ASSERT(j >= 0 && j < Y->in.size());
- foreach (Stmt *s, Y->statements()) {
+ for (Stmt *s : Y->statements()) {
if (Phi *phi = s->asPhi()) {
- Temp *t = phi->d->incoming[j]->asTemp();
+ Temp *t = phi->incoming[j]->asTemp();
unsigned newTmp = currentNumber(*t);
// qDebug()<<"I: replacing phi use"<<a<<"with"<<newTmp<<"in L"<<Y->index;
t->index = newTmp;
@@ -1845,11 +1728,11 @@ public:
{
grow();
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
if (!s)
continue;
@@ -1905,7 +1788,7 @@ public:
void applyToFunction()
{
- foreach (BasicBlock *bb, theFunction->basicBlocks()) {
+ for (BasicBlock *bb : theFunction->basicBlocks()) {
if (bb->isRemoved())
continue;
@@ -1979,6 +1862,11 @@ public:
return worklistSize == 0;
}
+ unsigned size() const
+ {
+ return worklistSize;
+ }
+
Stmt *takeNext(Stmt *last)
{
if (isEmpty())
@@ -2185,27 +2073,6 @@ protected:
}
};
-struct DiscoveredType {
- int type;
- MemberExpressionResolver *memberResolver;
-
- DiscoveredType() : type(UnknownType), memberResolver(0) {}
- DiscoveredType(Type t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
- explicit DiscoveredType(int t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
- explicit DiscoveredType(MemberExpressionResolver *memberResolver)
- : type(QObjectType)
- , memberResolver(memberResolver)
- { Q_ASSERT(memberResolver); }
-
- bool test(Type t) const { return type & t; }
- bool isNumber() const { return (type & NumberType) && !(type & ~NumberType); }
-
- bool operator!=(Type other) const { return type != other; }
- bool operator==(Type other) const { return type == other; }
- bool operator==(const DiscoveredType &other) const { return type == other.type; }
- bool operator!=(const DiscoveredType &other) const { return type != other.type; }
-};
-
class PropagateTempTypes: public StmtVisitor, ExprVisitor
{
const DefUses &defUses;
@@ -2274,7 +2141,7 @@ protected:
virtual void visitRet(Ret *s) { s->expr->accept(this); }
virtual void visitPhi(Phi *s) {
s->targetTemp->accept(this);
- foreach (Expr *e, s->d->incoming)
+ foreach (Expr *e, s->incoming)
e->accept(this);
}
};
@@ -2306,6 +2173,7 @@ class TypeInference: public StmtVisitor, public ExprVisitor
{}
};
TypingResult _ty;
+ Stmt *_currentStmt;
public:
TypeInference(QQmlEnginePrivate *qmlEngine, const DefUses &defUses)
@@ -2314,6 +2182,7 @@ public:
, _tempTypes(_defUses.tempCount())
, _worklist(0)
, _ty(UnknownType)
+ , _currentStmt(nullptr)
{}
void run(StatementWorklist &w) {
@@ -2330,7 +2199,10 @@ public:
QTextStream qout(&buf);
qout<<"Typing stmt ";
IRPrinter(&qout).print(s);
+ qout.flush();
qDebug("%s", buf.data().constData());
+
+ qDebug("%u left in the worklist", _worklist->size());
}
if (!run(s)) {
@@ -2341,6 +2213,7 @@ public:
QTextStream qout(&buf);
qout<<"Pushing back stmt: ";
IRPrinter(&qout).print(s);
+ qout.flush();
qDebug("%s", buf.data().constData());
}
} else {
@@ -2350,6 +2223,7 @@ public:
QTextStream qout(&buf);
qout<<"Finished: ";
IRPrinter(&qout).print(s);
+ qout.flush();
qDebug("%s", buf.data().constData());
}
}
@@ -2373,7 +2247,9 @@ private:
bool run(Stmt *s) {
TypingResult ty;
std::swap(_ty, ty);
- s->accept(this);
+ std::swap(_currentStmt, s);
+ _currentStmt->accept(this);
+ std::swap(_currentStmt, s);
std::swap(_ty, ty);
return ty.fullyTyped;
}
@@ -2407,11 +2283,16 @@ private:
QTextStream qout(&buf);
qout << "Pushing back dependent stmt: ";
IRPrinter(&qout).print(s);
+ qout.flush();
qDebug("%s", buf.data().constData());
}
}
- *_worklist += _defUses.uses(*t);
+ for (Stmt *s : qAsConst(_defUses.uses(*t))) {
+ if (s != _currentStmt) {
+ *_worklist += s;
+ }
+ }
}
} else {
e->type = (Type) ty.type;
@@ -2547,7 +2428,7 @@ protected:
if (_ty.fullyTyped && _ty.type.memberResolver && _ty.type.memberResolver->isValid()) {
MemberExpressionResolver *resolver = _ty.type.memberResolver;
- _ty.type.type = resolver->resolveMember(qmlEngine, resolver, e);
+ _ty.type = resolver->resolveMember(qmlEngine, resolver, e);
} else
_ty.type = VarType;
}
@@ -2569,9 +2450,9 @@ protected:
virtual void visitCJump(CJump *s) { _ty = run(s->cond); }
virtual void visitRet(Ret *s) { _ty = run(s->expr); }
virtual void visitPhi(Phi *s) {
- _ty = run(s->d->incoming[0]);
- for (int i = 1, ei = s->d->incoming.size(); i != ei; ++i) {
- TypingResult ty = run(s->d->incoming[i]);
+ _ty = run(s->incoming[0]);
+ for (int i = 1, ei = s->incoming.size(); i != ei; ++i) {
+ TypingResult ty = run(s->incoming[i]);
if (!ty.fullyTyped && _ty.fullyTyped) {
// When one of the temps not fully typed, we already know that we cannot completely type this node.
// So, pick the type we calculated upto this point, and wait until the unknown one will be typed.
@@ -2834,12 +2715,12 @@ public:
void run(IR::Function *f, StatementWorklist &worklist) {
_f = f;
- foreach (BasicBlock *bb, f->basicBlocks()) {
+ for (BasicBlock *bb : f->basicBlocks()) {
if (bb->isRemoved())
continue;
_conversions.clear();
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
_currStmt = s;
s->accept(this);
}
@@ -2890,7 +2771,7 @@ public:
_defUses.addUse(*source, conversion.stmt);
if (Phi *phi = conversion.stmt->asPhi()) {
- int idx = phi->d->incoming.indexOf(t);
+ int idx = phi->incoming.indexOf(t);
Q_ASSERT(idx != -1);
bb->in[idx]->insertStatementBeforeTerminator(convCall);
} else {
@@ -3042,14 +2923,15 @@ protected:
virtual void visitRet(Ret *s) { run(s->expr); }
virtual void visitPhi(Phi *s) {
Type ty = s->targetTemp->type;
- for (int i = 0, ei = s->d->incoming.size(); i != ei; ++i)
- run(s->d->incoming[i], ty);
+ for (int i = 0, ei = s->incoming.size(); i != ei; ++i)
+ run(s->incoming[i], ty);
}
};
void splitCriticalEdges(IR::Function *f, DominatorTree &df, StatementWorklist &worklist, DefUses &defUses)
{
- foreach (BasicBlock *toBB, f->basicBlocks()) {
+ const QVector<BasicBlock *> copy = f->basicBlocks();
+ for (BasicBlock *toBB : copy) {
if (toBB->isRemoved())
continue;
if (toBB->in.size() < 2)
@@ -3117,7 +2999,7 @@ void splitCriticalEdges(IR::Function *f, DominatorTree &df, StatementWorklist &w
df.setImmediateDominator(newBB, fromBB);
bool toNeedsNewIdom = true;
- foreach (BasicBlock *bb, toBB->in) {
+ for (BasicBlock *bb : toBB->in) {
if (bb != newBB && !df.dominates(toBB, bb)) {
toNeedsNewIdom = false;
break;
@@ -3227,7 +3109,7 @@ public:
backedges.clear();
- foreach (BasicBlock *in, bb->in)
+ for (BasicBlock *in : bb->in)
if (dt.dominates(bb, in))
backedges.push_back(in);
@@ -3304,7 +3186,7 @@ private:
// those predecessors are not in the current subloop. It might be the case
// that they are in other loops, which we will then add as a subloop to the
// current loop.
- foreach (BasicBlock *predIn, predIt->in)
+ for (BasicBlock *predIn : predIt->in)
if (predIn->containingGroup() != subloop)
worklist.push_back(predIn);
} else {
@@ -3315,7 +3197,7 @@ private:
predIt->setContainingGroup(loopHead);
// Add all incoming edges to the worklist.
- foreach (BasicBlock *bb, predIt->in)
+ for (BasicBlock *bb : predIt->in)
worklist.push_back(bb);
}
}
@@ -3327,7 +3209,7 @@ private:
void createLoopInfos(IR::Function *function)
{
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
if (BasicBlock *loopHeader = bb->containingGroup())
@@ -3400,7 +3282,7 @@ class BlockScheduler
{
Q_ASSERT(candidate->containingGroup() == currentGroup.group);
- foreach (BasicBlock *in, candidate->in) {
+ for (BasicBlock *in : candidate->in) {
if (emitted.alreadyProcessed(in))
continue;
@@ -3510,7 +3392,7 @@ public:
void checkCriticalEdges(QVector<BasicBlock *> basicBlocks) {
foreach (BasicBlock *bb, basicBlocks) {
if (bb && bb->out.size() > 1) {
- foreach (BasicBlock *bb2, bb->out) {
+ for (BasicBlock *bb2 : bb->out) {
if (bb2 && bb2->in.size() > 1) {
qDebug() << "found critical edge between block"
<< bb->index() << "and block" << bb2->index();
@@ -3545,28 +3427,28 @@ static void cleanupBasicBlocks(IR::Function *function)
reachableBlocks.setBit(bb->index());
- foreach (BasicBlock *outBB, bb->out) {
+ for (BasicBlock *outBB : bb->out) {
if (!reachableBlocks.at(outBB->index()))
postponed.append(outBB);
}
}
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved()) // the block has already been removed, so ignore it
continue;
if (reachableBlocks.at(bb->index())) // the block is reachable, so ignore it
continue;
- foreach (BasicBlock *outBB, bb->out) {
+ for (BasicBlock *outBB : bb->out) {
if (outBB->isRemoved() || !reachableBlocks.at(outBB->index()))
continue; // We do not need to unlink from blocks that are scheduled to be removed.
int idx = outBB->in.indexOf(bb);
if (idx != -1) {
outBB->in.remove(idx);
- foreach (Stmt *s, outBB->statements()) {
+ for (Stmt *s : outBB->statements()) {
if (Phi *phi = s->asPhi())
- phi->d->incoming.remove(idx);
+ phi->incoming.remove(idx);
else
break;
}
@@ -3581,9 +3463,9 @@ static void cleanupBasicBlocks(IR::Function *function)
inline Const *isConstPhi(Phi *phi)
{
- if (Const *c = phi->d->incoming[0]->asConst()) {
- for (int i = 1, ei = phi->d->incoming.size(); i != ei; ++i) {
- if (Const *cc = phi->d->incoming[i]->asConst()) {
+ if (Const *c = phi->incoming[0]->asConst()) {
+ for (int i = 1, ei = phi->incoming.size(); i != ei; ++i) {
+ if (Const *cc = phi->incoming[i]->asConst()) {
if (c->value != cc->value)
return 0;
if (!(c->type == cc->type || (c->type & NumberType && cc->type & NumberType)))
@@ -3684,8 +3566,8 @@ protected:
virtual void visitCJump(CJump *s) { check(s->cond); }
virtual void visitRet(Ret *s) { check(s->expr); }
virtual void visitPhi(Phi *s) {
- for (int i = 0, ei = s->d->incoming.size(); i != ei; ++i)
- check(s->d->incoming[i]);
+ for (int i = 0, ei = s->incoming.size(); i != ei; ++i)
+ check(s->incoming[i]);
}
private:
@@ -3746,11 +3628,11 @@ void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUs
if (!outStmt)
continue;
if (Phi *phi = outStmt->asPhi()) {
- if (Temp *t = phi->d->incoming[idx]->asTemp()) {
+ if (Temp *t = phi->incoming[idx]->asTemp()) {
defUses.removeUse(phi, *t);
W += defUses.defStmt(*t);
}
- phi->d->incoming.remove(idx);
+ phi->incoming.remove(idx);
W += phi;
} else {
break;
@@ -3800,14 +3682,14 @@ void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUs
continue;
// unlink all incoming edges
- foreach (BasicBlock *in, bb->in) {
+ for (BasicBlock *in : bb->in) {
int idx = in->out.indexOf(bb);
if (idx != -1)
in->out.remove(idx);
}
// unlink all outgoing edges, including "arguments" to phi statements
- foreach (BasicBlock *out, bb->out) {
+ for (BasicBlock *out : bb->out) {
if (out->isRemoved())
continue;
@@ -3823,7 +3705,7 @@ void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUs
}
// unlink all defs/uses from the statements in the basic block
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
if (!s)
continue;
@@ -3938,7 +3820,7 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
Util(qout).genLoop(l);
}
- foreach (BasicBlock *bb, f->basicBlocks()) {
+ for (BasicBlock *bb : f->basicBlocks()) {
if (bb->isRemoved())
continue;
@@ -3949,7 +3831,7 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
else
qout << ", shape=circle";
qout << "];\n";
- foreach (BasicBlock *out, bb->out)
+ for (BasicBlock *out : bb->out)
qout << " L" << idx << " -> L" << out->index() << "\n";
}
@@ -3987,9 +3869,9 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
}
// copy propagation:
- if (phi->d->incoming.size() == 1) {
+ if (phi->incoming.size() == 1) {
Temp *t = phi->targetTemp;
- Expr *e = phi->d->incoming.first();
+ Expr *e = phi->incoming.first();
QVector<Stmt *> newT2Uses;
replaceUses(t, e, W, &newT2Uses);
@@ -4420,14 +4302,14 @@ private:
void buildIntervals(BasicBlock *bb, BasicBlock *loopEnd)
{
LiveRegs live;
- foreach (BasicBlock *successor, bb->out) {
+ for (BasicBlock *successor : bb->out) {
live.unite(_liveIn[successor->index()]);
const int bbIndex = successor->in.indexOf(bb);
Q_ASSERT(bbIndex >= 0);
- foreach (Stmt *s, successor->statements()) {
+ for (Stmt *s : successor->statements()) {
if (Phi *phi = s->asPhi()) {
- if (Temp *t = phi->d->incoming.at(bbIndex)->asTemp())
+ if (Temp *t = phi->incoming.at(bbIndex)->asTemp())
live.insert(*t);
} else {
break;
@@ -4435,7 +4317,7 @@ private:
}
}
- QVector<Stmt *> statements = bb->statements();
+ const QVector<Stmt *> &statements = bb->statements();
foreach (const Temp &opd, live)
interval(&opd).addRange(start(bb), end(bb));
@@ -4483,7 +4365,7 @@ void removeUnreachleBlocks(IR::Function *function)
{
QVector<BasicBlock *> newSchedule;
newSchedule.reserve(function->basicBlockCount());
- foreach (BasicBlock *bb, function->basicBlocks())
+ for (BasicBlock *bb : function->basicBlocks())
if (!bb->isRemoved())
newSchedule.append(bb);
function->setScheduledBlocks(newSchedule);
@@ -4528,9 +4410,9 @@ public:
}
}
- foreach (BasicBlock *bb, function->basicBlocks())
+ for (BasicBlock *bb : function->basicBlocks())
if (!bb->isRemoved())
- foreach (Stmt *s, bb->statements())
+ for (Stmt *s : bb->statements())
s->accept(this);
if (convertArgs && function->formals.size() > 0)
@@ -4614,7 +4496,7 @@ public:
{
block = new BasicBlock(originalBlock->function, 0);
- foreach (Stmt *s, originalBlock->statements()) {
+ for (Stmt *s : originalBlock->statements()) {
s->accept(this);
clonedStmt->location = s->location;
}
@@ -4644,9 +4526,8 @@ protected:
clonedStmt = phi;
phi->targetTemp = clone(stmt->targetTemp);
- phi->d = new Phi::Data;
- foreach (Expr *in, stmt->d->incoming)
- phi->d->incoming.append(clone(in));
+ foreach (Expr *in, stmt->incoming)
+ phi->incoming.append(clone(in));
block->appendStatement(phi);
}
@@ -4731,7 +4612,8 @@ private:
// the terminators will automatically insert that edge). The blocks where the originals
// pointed to will have an extra incoming edge from the copied blocks.
- foreach (BasicBlock *in, loop->loopHeader->in) {
+ BasicBlock::IncomingEdges inCopy = loop->loopHeader->in;
+ for (BasicBlock *in : inCopy) {
if (unpeeled.loopHeader != in // this can happen for really tight loops (where there are no body blocks). This is a back-edge in that case.
&& !unpeeled.loopBody.contains(in) // if the edge is not coming from within the copied set, leave it alone
&& !dt.dominates(loop->loopHeader, in)) // an edge coming from within the loop (so a back-edge): this is handled when rewiring all outgoing edges
@@ -4805,7 +4687,7 @@ static void verifyCFG(IR::Function *function)
if (!DoVerification)
return;
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved()) {
Q_ASSERT(bb->in.isEmpty());
Q_ASSERT(bb->out.isEmpty());
@@ -4837,14 +4719,14 @@ static void verifyCFG(IR::Function *function)
}
// Check the outgoing edges:
- foreach (BasicBlock *out, bb->out) {
+ for (BasicBlock *out : bb->out) {
Q_UNUSED(out);
Q_ASSERT(!out->isRemoved());
Q_ASSERT(out->in.contains(bb));
}
// Check the incoming edges:
- foreach (BasicBlock *in, bb->in) {
+ for (BasicBlock *in : bb->in) {
Q_UNUSED(in);
Q_ASSERT(!in->isRemoved());
Q_ASSERT(in->out.contains(bb));
@@ -4861,7 +4743,7 @@ static void verifyImmediateDominators(const DominatorTree &dt, IR::Function *fun
dt.dumpImmediateDominators();
DominatorTree referenceTree(function);
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
@@ -4882,11 +4764,11 @@ static void verifyNoPointerSharing(IR::Function *function)
public:
void operator()(IR::Function *f)
{
- foreach (BasicBlock *bb, f->basicBlocks()) {
+ for (BasicBlock *bb : f->basicBlocks()) {
if (bb->isRemoved())
continue;
- foreach (Stmt *s, bb->statements())
+ for (Stmt *s : bb->statements())
s->accept(this);
}
}
@@ -4901,7 +4783,7 @@ static void verifyNoPointerSharing(IR::Function *function)
{
check(s);
s->targetTemp->accept(this);
- foreach (Expr *e, s->d->incoming)
+ foreach (Expr *e, s->incoming)
e->accept(this);
}
@@ -4950,11 +4832,11 @@ class RemoveLineNumbers: public SideEffectsChecker, public StmtVisitor
public:
static void run(IR::Function *function)
{
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
if (!hasSideEffects(s)) {
s->location = QQmlJS::AST::SourceLocation();
}
@@ -5166,13 +5048,13 @@ LifeTimeIntervals::LifeTimeIntervals(IR::Function *function)
// basic-block.
void LifeTimeIntervals::renumber(IR::Function *function)
{
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
if (bb->isRemoved())
continue;
_basicBlockPosition[bb->index()].start = _lastPosition + 1;
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
if (s->asPhi())
continue;
@@ -5202,7 +5084,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
function->removeSharedExpressions();
int statementCount = 0;
- foreach (BasicBlock *bb, function->basicBlocks())
+ for (BasicBlock *bb : function->basicBlocks())
if (!bb->isRemoved())
statementCount += bb->statementCount();
// showMeTheCode(function);
@@ -5332,15 +5214,15 @@ void Optimizer::convertOutOfSSA() {
// There should be no critical edges at this point.
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
MoveMapping moves;
- foreach (BasicBlock *successor, bb->out) {
+ for (BasicBlock *successor : bb->out) {
const int inIdx = successor->in.indexOf(bb);
Q_ASSERT(inIdx >= 0);
- foreach (Stmt *s, successor->statements()) {
+ for (Stmt *s : successor->statements()) {
if (Phi *phi = s->asPhi()) {
- moves.add(clone(phi->d->incoming[inIdx], function),
+ moves.add(clone(phi->incoming[inIdx], function),
clone(phi->targetTemp, function)->asTemp());
} else {
break;
@@ -5368,7 +5250,7 @@ void Optimizer::convertOutOfSSA() {
moves.insertMoves(bb, function, true);
}
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
while (!bb->isEmpty()) {
if (bb->statements().first()->asPhi()) {
bb->removeStatement(0);
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index bd93da324d..1104608055 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -64,6 +64,8 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public
Q_OBJECT
public:
+ static const int s_numMessagesPerBatch = 1000;
+
QQmlAbstractProfilerAdapter(QObject *parent = 0) :
QObject(parent), service(0), waiting(true), featuresEnabled(0) {}
virtual ~QQmlAbstractProfilerAdapter() {}
diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp
index 64a951d53b..9276bd0544 100644
--- a/src/qml/debugger/qqmldebug.cpp
+++ b/src/qml/debugger/qqmldebug.cpp
@@ -134,22 +134,11 @@ void QQmlDebuggingEnabler::setServices(const QStringList &services)
*/
bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName)
{
-#ifndef QQML_NO_DEBUG_PROTOCOL
- QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer"));
- QQmlDebugConnector *connector = QQmlDebugConnector::instance();
- if (connector) {
- QVariantHash configuration;
- configuration[QLatin1String("portFrom")] = configuration[QLatin1String("portTo")] = port;
- configuration[QLatin1String("block")] = (mode == WaitForClient);
- configuration[QLatin1String("hostAddress")] = hostName;
- return connector->open(configuration);
- }
-#else
- Q_UNUSED(port);
- Q_UNUSED(mode);
- Q_UNUSED(hostName);
-#endif
- return false;
+ QVariantHash configuration;
+ configuration[QLatin1String("portFrom")] = configuration[QLatin1String("portTo")] = port;
+ configuration[QLatin1String("block")] = (mode == WaitForClient);
+ configuration[QLatin1String("hostAddress")] = hostName;
+ return startDebugConnector(QLatin1String("QQmlDebugServer"), configuration);
}
/*!
@@ -164,18 +153,33 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q
*/
bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, StartMode mode)
{
+ QVariantHash configuration;
+ configuration[QLatin1String("fileName")] = socketFileName;
+ configuration[QLatin1String("block")] = (mode == WaitForClient);
+ return startDebugConnector(QLatin1String("QQmlDebugServer"), configuration);
+}
+
+/*!
+ * \since 5.7
+ *
+ * Enables debugging for QML engines created after calling this function. A debug connector plugin
+ * specified by \a pluginName will be loaded and started using the given \a configuration. Supported
+ * configuration entries and their semantics depend on the plugin being loaded. You can only start
+ * one debug connector at a time. A debug connector may have already been started if the
+ * -qmljsdebugger= command line argument was given. This method returns \c true if a new debug
+ * connector was successfully started, or \c false otherwise.
+ */
+bool QQmlDebuggingEnabler::startDebugConnector(const QString &pluginName,
+ const QVariantHash &configuration)
+{
#ifndef QQML_NO_DEBUG_PROTOCOL
- QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer"));
+ QQmlDebugConnector::setPluginKey(pluginName);
QQmlDebugConnector *connector = QQmlDebugConnector::instance();
- if (connector) {
- QVariantHash configuration;
- configuration[QLatin1String("fileName")] = socketFileName;
- configuration[QLatin1String("block")] = (mode == WaitForClient);
+ if (connector)
return connector->open(configuration);
- }
#else
- Q_UNUSED(fileName);
- Q_UNUSED(mode);
+ Q_UNUSED(pluginName);
+ Q_UNUSED(configuration);
#endif
return false;
}
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index eebebefe62..660b9e4d46 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -42,6 +42,7 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
@@ -65,6 +66,8 @@ struct Q_QML_EXPORT QQmlDebuggingEnabler
const QString &hostName = QString());
static bool connectToLocalDebugger(const QString &socketFileName,
StartMode mode = DoNotWaitForClient);
+ static bool startDebugConnector(const QString &pluginName,
+ const QVariantHash &configuration = QVariantHash());
};
// Execute code in constructor before first QQmlEngine is instantiated
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index 6edd28ea01..e6d1a218ad 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -127,18 +127,15 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
}
if (!params->instance) {
- const QString serverConnector = QStringLiteral("QQmlDebugServer");
- const QString nativeConnector = QStringLiteral("QQmlNativeDebugConnector");
- const bool isNative = params->arguments.startsWith(QLatin1String("native"));
if (!params->pluginKey.isEmpty()) {
- if (params->pluginKey == serverConnector || params->pluginKey == nativeConnector)
- params->instance = loadQQmlDebugConnector(params->pluginKey);
- else
- return 0; // We cannot load anything else, yet
+ params->instance = loadQQmlDebugConnector(params->pluginKey);
} else if (params->arguments.isEmpty()) {
return 0; // no explicit class name given and no command line arguments
} else {
- params->instance = loadQQmlDebugConnector(isNative ? nativeConnector : serverConnector);
+ params->instance = loadQQmlDebugConnector(
+ params->arguments.startsWith(QLatin1String("native")) ?
+ QStringLiteral("QQmlNativeDebugConnector") :
+ QStringLiteral("QQmlDebugServer"));
}
if (params->instance) {
diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc
index 31133c862f..f32574fcc1 100644
--- a/src/qml/doc/src/qmltypereference.qdoc
+++ b/src/qml/doc/src/qmltypereference.qdoc
@@ -55,7 +55,7 @@ are also provided by the \c QtQuick namespace which may be imported as
follows:
\qml
-import QtQuick 2.5
+import QtQuick 2.7
\endqml
See the \l{Qt Quick} module documentation for more information about the \c
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index a6e085a913..131e0a5b0a 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -180,9 +180,9 @@ public:
_calls.reserve(function->statementCount() / 3);
_hints.resize(function->tempCount);
- foreach (BasicBlock *bb, function->basicBlocks()) {
+ for (BasicBlock *bb : function->basicBlocks()) {
_currentBB = bb;
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
_currentStmt = s;
s->accept(this);
}
@@ -702,8 +702,8 @@ protected: // IRDecoder
virtual void visitPhi(IR::Phi *s)
{
addDef(s->targetTemp, true);
- for (int i = 0, ei = s->d->incoming.size(); i < ei; ++i) {
- Expr *e = s->d->incoming.at(i);
+ for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
+ Expr *e = s->incoming.at(i);
if (Temp *t = e->asTemp()) {
// The actual use of an incoming value in a phi node is right before the terminator
// of the other side of the incoming edge.
@@ -821,8 +821,8 @@ class ResolutionPhase: protected StmtVisitor, protected ExprVisitor {
const QVector<const RegisterInfo *> &_fpRegs;
Stmt *_currentStmt;
- QVector<Move *> _loads;
- QVector<Move *> _stores;
+ std::vector<Move *> _loads;
+ std::vector<Move *> _stores;
QHash<BasicBlock *, QList<const LifeTimeInterval *> > _liveAtStart;
QHash<BasicBlock *, QList<const LifeTimeInterval *> > _liveAtEnd;
@@ -872,7 +872,7 @@ private:
{
QVector<Stmt *> newStatements;
- foreach (BasicBlock *bb, _function->basicBlocks()) {
+ for (BasicBlock *bb : _function->basicBlocks()) {
_currentStmt = 0;
QVector<Stmt *> statements = bb->statements();
@@ -892,13 +892,13 @@ private:
else
addNewIntervals(defPosition(_currentStmt));
_currentStmt->accept(this);
- foreach (Move *load, _loads)
+ for (Move *load : _loads)
newStatements.append(load);
if (_currentStmt->asPhi())
newStatements.prepend(_currentStmt);
else
newStatements.append(_currentStmt);
- foreach (Move *store, _stores)
+ for (Move *store : _stores)
newStatements.append(store);
}
@@ -912,7 +912,7 @@ private:
os << "Intervals live at the start of L" << bb->index() << ":" << endl;
if (_liveAtStart[bb].isEmpty())
os << "\t(none)" << endl;
- foreach (const LifeTimeInterval *i, _liveAtStart[bb]) {
+ for (const LifeTimeInterval *i : _liveAtStart.value(bb)) {
os << "\t";
i->dump(os);
os << endl;
@@ -920,7 +920,7 @@ private:
os << "Intervals live at the end of L" << bb->index() << ":" << endl;
if (_liveAtEnd[bb].isEmpty())
os << "\t(none)" << endl;
- foreach (const LifeTimeInterval *i, _liveAtEnd[bb]) {
+ for (const LifeTimeInterval *i : _liveAtEnd.value(bb)) {
os << "\t";
i->dump(os);
os << endl;
@@ -943,7 +943,7 @@ private:
Q_ASSERT(pReg);
int spillSlot = _assignedSpillSlots[i->temp().index];
if (spillSlot != RegisterAllocator::InvalidSpillSlot)
- _stores.append(generateSpill(spillSlot, i->temp().type, pReg->reg<int>()));
+ _stores.push_back(generateSpill(spillSlot, i->temp().type, pReg->reg<int>()));
}
void addNewIntervals(int position)
@@ -976,15 +976,15 @@ private:
void resolve()
{
- foreach (BasicBlock *bb, _function->basicBlocks()) {
- foreach (BasicBlock *bbOut, bb->out)
+ for (BasicBlock *bb : _function->basicBlocks()) {
+ for (BasicBlock *bbOut : bb->out)
resolveEdge(bb, bbOut);
}
}
Phi *findDefPhi(const Temp &t, BasicBlock *bb) const
{
- foreach (Stmt *s, bb->statements()) {
+ for (Stmt *s : bb->statements()) {
Phi *phi = s->asPhi();
if (!phi)
return 0;
@@ -1017,21 +1017,21 @@ private:
int successorStart = _intervals->startPosition(successor);
Q_ASSERT(successorStart > 0);
- foreach (const LifeTimeInterval *it, _liveAtStart[successor]) {
+ for (const LifeTimeInterval *it : _liveAtStart.value(successor)) {
bool isPhiTarget = false;
Expr *moveFrom = 0;
if (it->start() == successorStart) {
if (Phi *phi = findDefPhi(it->temp(), successor)) {
isPhiTarget = true;
- Expr *opd = phi->d->incoming[successor->in.indexOf(predecessor)];
+ Expr *opd = phi->incoming[successor->in.indexOf(predecessor)];
if (opd->asConst()) {
moveFrom = opd;
} else {
Temp *t = opd->asTemp();
Q_ASSERT(t);
- foreach (const LifeTimeInterval *it2, _liveAtEnd[predecessor]) {
+ for (const LifeTimeInterval *it2 : _liveAtEnd.value(predecessor)) {
if (it2->temp() == *t
&& it2->reg() != LifeTimeInterval::InvalidRegister
&& it2->covers(predecessorEnd)) {
@@ -1046,7 +1046,7 @@ private:
}
}
} else {
- foreach (const LifeTimeInterval *predIt, _liveAtEnd[predecessor]) {
+ for (const LifeTimeInterval *predIt : _liveAtEnd.value(predecessor)) {
if (predIt->temp() == it->temp()) {
if (predIt->reg() != LifeTimeInterval::InvalidRegister
&& predIt->covers(predecessorEnd)) {
@@ -1191,7 +1191,7 @@ protected:
Q_ASSERT(i->isSplitFromInterval());
const RegisterInfo *pReg = platformRegister(*i);
Q_ASSERT(pReg);
- _loads.append(generateUnspill(i->temp(), pReg->reg<int>()));
+ _loads.push_back(generateUnspill(i->temp(), pReg->reg<int>()));
}
if (i->reg() != LifeTimeInterval::InvalidRegister &&
@@ -1303,7 +1303,7 @@ void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
qout << "Ranges:" << endl;
QVector<LifeTimeInterval *> intervals = _unhandled;
std::reverse(intervals.begin(), intervals.end());
- foreach (const LifeTimeInterval *r, intervals) {
+ for (const LifeTimeInterval *r : qAsConst(intervals)) {
r->dump(qout);
qout << endl;
}
@@ -1490,11 +1490,11 @@ void RegisterAllocator::linearScan()
}
}
- foreach (LifeTimeInterval *r, _active)
+ for (LifeTimeInterval *r : qAsConst(_active))
if (!r->isFixedInterval())
_handled.append(r);
_active.clear();
- foreach (LifeTimeInterval *r, _inactive)
+ for (LifeTimeInterval *r : qAsConst(_inactive))
if (!r->isFixedInterval())
_handled.append(r);
_inactive.clear();
@@ -1922,7 +1922,7 @@ void RegisterAllocator::dump(IR::Function *function) const
qout << "Ranges:" << endl;
QVector<LifeTimeInterval *> handled = _handled;
std::sort(handled.begin(), handled.end(), LifeTimeInterval::lessThanForTemp);
- foreach (const LifeTimeInterval *r, handled) {
+ for (const LifeTimeInterval *r : qAsConst(handled)) {
r->dump(qout);
qout << endl;
}
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index 300990873d..6ecd0c7ec0 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -111,7 +111,7 @@ private:
friend inline bool qjsvalue_cast_helper(const QJSValue &, int, void *);
protected:
- QJSEngine(QJSEnginePrivate &dd, QObject *parent = 0);
+ QJSEngine(QJSEnginePrivate &dd, QObject *parent = Q_NULLPTR);
private:
QV8Engine *d;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 317eb7a8a7..55ea1f91c3 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -576,15 +576,6 @@ ExecutionContext *ExecutionEngine::pushGlobalContext()
return currentContext;
}
-ExecutionContext *ExecutionEngine::parentContext(ExecutionContext *context) const
-{
- Value *offset = static_cast<Value *>(context) + 1;
- Q_ASSERT(offset->isInteger());
- int o = offset->integerValue();
- return o ? context - o : 0;
-}
-
-
Heap::Object *ExecutionEngine::newObject()
{
return memoryManager->allocObject<Object>();
@@ -770,27 +761,6 @@ Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o)
return obj->d();
}
-Heap::QmlContext *ExecutionEngine::qmlContext() const
-{
- Heap::ExecutionContext *ctx = current;
-
- // get the correct context when we're within a builtin function
- if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
- ctx = parentContext(currentContext)->d();
-
- if (!ctx->outer)
- return 0;
-
- while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
- ctx = ctx->outer;
-
- Q_ASSERT(ctx);
- if (ctx->type != Heap::ExecutionContext::Type_QmlContext)
- return 0;
-
- return static_cast<Heap::QmlContext *>(ctx);
-}
-
QObject *ExecutionEngine::qmlScopeObject() const
{
Heap::QmlContext *ctx = qmlContext();
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 12ed98e6e7..7da4a1c3c1 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -500,6 +500,35 @@ inline void ExecutionEngine::popContext()
current = currentContext->d();
}
+inline ExecutionContext *ExecutionEngine::parentContext(ExecutionContext *context) const
+{
+ Value *offset = static_cast<Value *>(context) + 1;
+ Q_ASSERT(offset->isInteger());
+ int o = offset->integerValue();
+ return o ? context - o : 0;
+}
+
+inline Heap::QmlContext *ExecutionEngine::qmlContext() const
+{
+ Heap::ExecutionContext *ctx = current;
+
+ // get the correct context when we're within a builtin function
+ if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
+ ctx = parentContext(currentContext)->d();
+
+ if (!ctx->outer)
+ return 0;
+
+ while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
+ ctx = ctx->outer;
+
+ Q_ASSERT(ctx);
+ if (ctx->type != Heap::ExecutionContext::Type_QmlContext)
+ return 0;
+
+ return static_cast<Heap::QmlContext *>(ctx);
+}
+
inline
void Heap::Base::mark(QV4::ExecutionEngine *engine)
{
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index dd86c50270..470791fb00 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -141,8 +141,8 @@ struct ReadAccessor {
{
Q_ASSERT(property.accessors);
- property.accessors->read(object, property.accessorData, output);
- if (n) property.accessors->notifier(object, property.accessorData, n);
+ property.accessors->read(object, output);
+ if (n) property.accessors->notifier(object, n);
}
};
diff --git a/src/qml/jsruntime/qv4util_p.h b/src/qml/jsruntime/qv4util_p.h
index 3ffcc8a846..59c12c5e46 100644
--- a/src/qml/jsruntime/qv4util_p.h
+++ b/src/qml/jsruntime/qv4util_p.h
@@ -51,6 +51,9 @@
//
#include "qv4global_p.h"
+#include <QtCore/QBitArray>
+#include <algorithm>
+#include <vector>
QT_BEGIN_NAMESPACE
@@ -76,6 +79,130 @@ private:
TemporaryAssignment operator=(const TemporaryAssignment<T>&);
};
+#if !defined(BROKEN_STD_VECTOR_BOOL_OR_BROKEN_STD_FIND)
+// Sanity:
+class BitVector
+{
+ std::vector<bool> bits;
+
+public:
+ BitVector(int size = 0, bool value = false)
+ : bits(size, value)
+ {}
+
+ void reserve(int size)
+ { bits.reserve(size); }
+
+ int size() const
+ {
+ Q_ASSERT(bits.size() < INT_MAX);
+ return static_cast<int>(bits.size());
+ }
+
+ void resize(int newSize)
+ { bits.resize(newSize); }
+
+ void resize(int newSize, bool newValue)
+ { bits.resize(newSize, newValue); }
+
+ void assign(int newSize, bool value)
+ { bits.assign(newSize, value); }
+
+ int findNext(int start, bool value, bool wrapAround) const
+ {
+ // The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an
+ // iterator pointing to the last element. It will not be set to ::end(), but beyond
+ // that. (It will be set to the first multiple of the native word size that is bigger
+ // than size().)
+ //
+ // See http://llvm.org/bugs/show_bug.cgi?id=19663
+ //
+ // The work-around is to calculate the distance, and compare it to the size() to see if it's
+ // beyond the end, or take the minimum of the distance and the size.
+
+ size_t pos = std::distance(bits.begin(),
+ std::find(bits.begin() + start, bits.end(), value));
+ if (wrapAround && pos >= static_cast<size_t>(size()))
+ pos = std::distance(bits.begin(),
+ std::find(bits.begin(), bits.begin() + start, value));
+
+ pos = qMin(pos, static_cast<size_t>(size()));
+
+ Q_ASSERT(pos <= static_cast<size_t>(size()));
+ Q_ASSERT(pos < INT_MAX);
+
+ return static_cast<int>(pos);
+ }
+
+ bool at(int idx) const
+ { return bits.at(idx); }
+
+ void setBit(int idx)
+ { bits[idx] = true; }
+
+ void clearBit(int idx)
+ { bits[idx] = false; }
+};
+#else // Insanity:
+class BitVector
+{
+ QBitArray bits;
+
+public:
+ BitVector(int size = 0, bool value = false)
+ : bits(size, value)
+ {}
+
+ void reserve(int size)
+ { Q_UNUSED(size); }
+
+ int size() const
+ { return bits.size(); }
+
+ void resize(int newSize)
+ { bits.resize(newSize); }
+
+ void resize(int newSize, bool newValue)
+ {
+ int oldSize = bits.size();
+ bits.resize(newSize);
+ bits.fill(newValue, oldSize, bits.size());
+ }
+
+ void assign(int newSize, bool value)
+ {
+ bits.resize(newSize);
+ bits.fill(value);
+ }
+
+ int findNext(int start, bool value, bool wrapAround) const
+ {
+ for (int i = start, ei = size(); i < ei; ++i) {
+ if (at(i) == value)
+ return i;
+ }
+
+ if (wrapAround) {
+ for (int i = 0, ei = start; i < ei; ++i) {
+ if (at(i) == value)
+ return i;
+ }
+ }
+
+ return size();
+ }
+
+ bool at(int idx) const
+ { return bits.at(idx); }
+
+ void setBit(int idx)
+ { bits[idx] = true; }
+
+ void clearBit(int idx)
+ { bits[idx] = false; }
+};
+#endif
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index e8320b33d2..514bdafb48 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -119,11 +119,14 @@ struct Q_QML_PRIVATE_EXPORT Value
Q_ALWAYS_INLINE quint32 value() const { return _val >> 32; }
#endif
-#ifdef QV4_USE_64_BIT_VALUE_ENCODING
+#if defined(V4_BOOTSTRAP)
+ Q_ALWAYS_INLINE Heap::Base *m() const { Q_UNREACHABLE(); return Q_NULLPTR; }
+ Q_ALWAYS_INLINE void setM(Heap::Base *b) { Q_UNUSED(b); Q_UNREACHABLE(); }
+#elif defined(QV4_USE_64_BIT_VALUE_ENCODING)
Q_ALWAYS_INLINE Heap::Base *m() const { Heap::Base *b; memcpy(&b, &_val, 8); return b; }
Q_ALWAYS_INLINE void setM(Heap::Base *b) { memcpy(&_val, &b, 8); }
#else // !QV4_USE_64_BIT_VALUE_ENCODING
- Q_ALWAYS_INLINE Heap::Base *m() const { Heap::Base *b; quint32 v = value(); memcpy(&b, &v, 4); return b; }
+ Q_ALWAYS_INLINE Heap::Base *m() const { Q_STATIC_ASSERT(sizeof(Heap::Base*) == sizeof(quint32)); Heap::Base *b; quint32 v = value(); memcpy(&b, &v, 4); return b; }
Q_ALWAYS_INLINE void setM(Heap::Base *b) { quint32 v; memcpy(&v, &b, 4); setValue(v); }
#endif
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h
index 3659271bc6..08609e2961 100644
--- a/src/qml/parser/qqmljsmemorypool_p.h
+++ b/src/qml/parser/qqmljsmemorypool_p.h
@@ -94,7 +94,7 @@ public:
inline void *allocate(size_t size)
{
size = (size + 7) & ~7;
- if (_ptr && (_ptr + size < _end)) {
+ if (Q_LIKELY(_ptr && (_ptr + size < _end))) {
void *addr = _ptr;
_ptr += size;
return addr;
@@ -111,7 +111,7 @@ public:
template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); }
private:
- void *allocate_helper(size_t size)
+ Q_NEVER_INLINE void *allocate_helper(size_t size)
{
Q_ASSERT(size < BLOCK_SIZE);
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 4ddac0c2c6..6ff3e4a11b 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -54,7 +54,6 @@
#include <QtCore/qglobal.h>
#include <QtCore/qstring.h>
#include <private/qv4string_p.h>
-#include <private/qv4scopedvalue_p.h>
#include <private/qflagpointer_p.h>
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index a71d06f7de..8fb710ad9d 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -111,10 +111,11 @@ int qmlRegisterType()
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- 0, 0,
+ 0,
+ Q_NULLPTR,
QString(),
- 0, 0, 0, 0, &T::staticMetaObject,
+ Q_NULLPTR, 0, 0, Q_NULLPTR, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -123,9 +124,9 @@ int qmlRegisterType()
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
- 0,
+ Q_NULLPTR,
0
};
@@ -144,7 +145,8 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- 0, 0,
+ 0,
+ Q_NULLPTR,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -156,9 +158,9 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
- 0,
+ Q_NULLPTR,
0
};
@@ -175,7 +177,8 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- 0, 0,
+ 0,
+ Q_NULLPTR,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -187,9 +190,9 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
- 0,
+ Q_NULLPTR,
metaObjectRevision
};
@@ -213,7 +216,8 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- 0, 0,
+ 0,
+ Q_NULLPTR,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -227,7 +231,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- 0,
+ Q_NULLPTR,
0
};
@@ -256,9 +260,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
- 0,
+ Q_NULLPTR,
0
};
@@ -287,9 +291,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
- 0,
+ Q_NULLPTR,
metaObjectRevision
};
@@ -318,9 +322,9 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
- 0,
+ Q_NULLPTR,
metaObjectRevision
};
@@ -338,10 +342,11 @@ int qmlRegisterExtendedType()
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- 0, 0,
+ 0,
+ Q_NULLPTR,
QString(),
- 0, 0, 0, 0, &T::staticMetaObject,
+ Q_NULLPTR, 0, 0, Q_NULLPTR, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -352,7 +357,7 @@ int qmlRegisterExtendedType()
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- 0,
+ Q_NULLPTR,
0
};
@@ -391,7 +396,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- 0,
+ Q_NULLPTR,
0
};
@@ -441,7 +446,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- 0, 0,
+ Q_NULLPTR, Q_NULLPTR,
parser,
0
@@ -536,7 +541,7 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
uri, versionMajor, versionMinor, typeName,
- callback, 0, 0, 0, 0
+ callback, Q_NULLPTR, Q_NULLPTR, 0, 0
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
@@ -554,7 +559,7 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
uri, versionMajor, versionMinor, typeName,
- 0, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0
+ Q_NULLPTR, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
diff --git a/src/qml/qml/qqmlaccessors_p.h b/src/qml/qml/qqmlaccessors_p.h
index cae4e2c2ff..55562a5307 100644
--- a/src/qml/qml/qqmlaccessors_p.h
+++ b/src/qml/qml/qqmlaccessors_p.h
@@ -103,7 +103,7 @@ class QQmlNotifier;
} while (false);
#define QML_PRIVATE_ACCESSOR(clazz, cpptype, name, variable) \
- static void clazz ## _ ## name ## Read(QObject *o, qintptr, void *rv) \
+ static void clazz ## _ ## name ## Read(QObject *o, void *rv) \
{ \
clazz ## Private *d = clazz ## Private::get(static_cast<clazz *>(o)); \
*static_cast<cpptype *>(rv) = d->variable; \
@@ -114,8 +114,8 @@ class QQmlNotifier;
class QQmlAccessors
{
public:
- void (*read)(QObject *object, qintptr property, void *output);
- void (*notifier)(QObject *object, qintptr property, QQmlNotifier **notifier);
+ void (*read)(QObject *object, void *output);
+ void (*notifier)(QObject *object, QQmlNotifier **notifier);
};
namespace QQmlAccessorProperties {
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
index 59667a1841..ff7dce5f8b 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -53,9 +53,9 @@ class Q_QML_EXPORT QQmlApplicationEngine : public QQmlEngine
{
Q_OBJECT
public:
- QQmlApplicationEngine(QObject *parent=0);
- QQmlApplicationEngine(const QUrl &url, QObject *parent=0);
- QQmlApplicationEngine(const QString &filePath, QObject *parent=0);
+ QQmlApplicationEngine(QObject *parent = Q_NULLPTR);
+ QQmlApplicationEngine(const QUrl &url, QObject *parent = Q_NULLPTR);
+ QQmlApplicationEngine(const QString &filePath, QObject *parent = Q_NULLPTR);
~QQmlApplicationEngine();
QList<QObject*> rootObjects();
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index 0e226320d6..aefbf20aff 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -72,12 +72,12 @@ public:
enum CompilationMode { PreferSynchronous, Asynchronous };
Q_ENUM(CompilationMode)
- QQmlComponent(QObject *parent = 0);
- QQmlComponent(QQmlEngine *, QObject *parent=0);
- QQmlComponent(QQmlEngine *, const QString &fileName, QObject *parent = 0);
- QQmlComponent(QQmlEngine *, const QString &fileName, CompilationMode mode, QObject *parent = 0);
- QQmlComponent(QQmlEngine *, const QUrl &url, QObject *parent = 0);
- QQmlComponent(QQmlEngine *, const QUrl &url, CompilationMode mode, QObject *parent = 0);
+ QQmlComponent(QObject *parent = Q_NULLPTR);
+ QQmlComponent(QQmlEngine *, QObject *parent = Q_NULLPTR);
+ QQmlComponent(QQmlEngine *, const QString &fileName, QObject *parent = Q_NULLPTR);
+ QQmlComponent(QQmlEngine *, const QString &fileName, CompilationMode mode, QObject *parent = Q_NULLPTR);
+ QQmlComponent(QQmlEngine *, const QUrl &url, QObject *parent = Q_NULLPTR);
+ QQmlComponent(QQmlEngine *, const QUrl &url, CompilationMode mode, QObject *parent = Q_NULLPTR);
virtual ~QQmlComponent();
enum Status { Null, Ready, Loading, Error };
@@ -96,12 +96,12 @@ public:
QUrl url() const;
- virtual QObject *create(QQmlContext *context = 0);
+ virtual QObject *create(QQmlContext *context = Q_NULLPTR);
virtual QObject *beginCreate(QQmlContext *);
virtual void completeCreate();
- void create(QQmlIncubator &, QQmlContext *context = 0,
- QQmlContext *forContext = 0);
+ void create(QQmlIncubator &, QQmlContext *context = Q_NULLPTR,
+ QQmlContext *forContext = Q_NULLPTR);
QQmlContext *creationContext() const;
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index f759f46af5..65a337f4e5 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -95,7 +95,7 @@ QQmlContextPrivate::QQmlContextPrivate()
by name in the context, as though they were all individually added through calls
to QQmlContext::setContextProperty(). Changes to the property's values are
detected through the property's notify signal. Setting a context object is both
- faster and easier than manually adding and maintaing context property values.
+ faster and easier than manually adding and maintaining context property values.
The following example has the same effect as the previous one, but it uses a context
object.
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index c6b5d44f5a..781eac44fc 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -62,8 +62,8 @@ class Q_QML_EXPORT QQmlContext : public QObject
Q_DECLARE_PRIVATE(QQmlContext)
public:
- QQmlContext(QQmlEngine *parent, QObject *objParent=0);
- QQmlContext(QQmlContext *parent, QObject *objParent=0);
+ QQmlContext(QQmlEngine *parent, QObject *objParent = Q_NULLPTR);
+ QQmlContext(QQmlContext *parent, QObject *objParent = Q_NULLPTR);
virtual ~QQmlContext();
bool isValid() const;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 057f4b54c0..48d596418d 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -66,6 +66,7 @@
#include <private/qflagpointer_p.h>
#include <private/qqmlguard_p.h>
+#include <private/qv4compileddata_p.h>
#include <private/qv4identifier_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 28bd66047e..132af78f80 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -97,7 +97,7 @@ class Q_QML_EXPORT QQmlEngine : public QJSEngine
Q_PROPERTY(QString offlineStoragePath READ offlineStoragePath WRITE setOfflineStoragePath)
Q_OBJECT
public:
- QQmlEngine(QObject *p = 0);
+ explicit QQmlEngine(QObject *p = Q_NULLPTR);
virtual ~QQmlEngine();
QQmlContext *rootContext() const;
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 7258ffe6ed..795a505742 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -375,7 +375,7 @@ const QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlEngine *e)
{
Q_ASSERT(e);
- return e->d_func();
+ return e ? e->d_func() : nullptr;
}
QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContext *c)
diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h
index 0aff4884f9..5239d59c8a 100644
--- a/src/qml/qml/qqmlexpression.h
+++ b/src/qml/qml/qqmlexpression.h
@@ -60,8 +60,8 @@ class Q_QML_EXPORT QQmlExpression : public QObject
Q_OBJECT
public:
QQmlExpression();
- QQmlExpression(QQmlContext *, QObject *, const QString &, QObject * = 0);
- explicit QQmlExpression(const QQmlScriptString &, QQmlContext * = 0, QObject * = 0, QObject * = 0);
+ QQmlExpression(QQmlContext *, QObject *, const QString &, QObject * = Q_NULLPTR);
+ explicit QQmlExpression(const QQmlScriptString &, QQmlContext * = Q_NULLPTR, QObject * = Q_NULLPTR, QObject * = Q_NULLPTR);
virtual ~QQmlExpression();
QQmlEngine *engine() const;
@@ -84,7 +84,7 @@ public:
void clearError();
QQmlError error() const;
- QVariant evaluate(bool *valueIsUndefined = 0);
+ QVariant evaluate(bool *valueIsUndefined = Q_NULLPTR);
Q_SIGNALS:
void valueChanged();
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index d0ee16ac50..de482d0352 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -58,7 +58,7 @@ class Q_QML_EXPORT QQmlExtensionPlugin
Q_INTERFACES(QQmlExtensionInterface)
Q_INTERFACES(QQmlTypesExtensionInterface)
public:
- explicit QQmlExtensionPlugin(QObject *parent = 0);
+ explicit QQmlExtensionPlugin(QObject *parent = Q_NULLPTR);
~QQmlExtensionPlugin();
QUrl baseUrl() const;
diff --git a/src/qml/qml/qqmlfileselector.h b/src/qml/qml/qqmlfileselector.h
index 34ba4d7a56..03b951420e 100644
--- a/src/qml/qml/qqmlfileselector.h
+++ b/src/qml/qml/qqmlfileselector.h
@@ -54,7 +54,7 @@ class Q_QML_EXPORT QQmlFileSelector : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QQmlFileSelector)
public:
- QQmlFileSelector(QQmlEngine* engine, QObject* parent=0);
+ explicit QQmlFileSelector(QQmlEngine *engine, QObject *parent = Q_NULLPTR);
~QQmlFileSelector();
QFileSelector *selector() const Q_DECL_NOTHROW;
void setSelector(QFileSelector *selector);
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 0014ccd3ba..d6c81bcc49 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -888,6 +888,11 @@ bool QQmlImportsPrivate::populatePluginPairVector(QVector<StaticPluginPair> &res
}
#endif
+static inline QString msgCannotLoadPlugin(const QString &uri, const QString &why)
+{
+ return QQmlImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri, why);
+}
+
/*!
Import an extension defined by a qmldir file.
@@ -949,7 +954,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
// The reason is that the lower level may add url and line/column numbering information.
QQmlError poppedError = errors->takeFirst();
QQmlError error;
- error.setDescription(QQmlImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(poppedError.description()));
+ error.setDescription(msgCannotLoadPlugin(uri, poppedError.description()));
error.setUrl(QUrl::fromLocalFile(qmldirFilePath));
errors->prepend(error);
}
@@ -1020,10 +1025,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
if (errors) {
QQmlError error;
- error.setDescription(
- QQmlImportDatabase::tr(
- "plugin cannot be loaded for module \"%1\": library loading is disabled")
- .arg(uri));
+ error.setDescription(msgCannotLoadPlugin(uri, QQmlImportDatabase::tr("library loading is disabled")));
error.setUrl(QUrl::fromLocalFile(qmldirFilePath));
errors->prepend(error);
}
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index aef0916239..15d0a571a5 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -298,7 +298,7 @@ void QQmlPropertyCapture::registerQmlDependencies(QV4::ExecutionEngine *engine,
// Let the caller check and avoid the function call :)
Q_ASSERT(compiledFunction->hasQmlDependencies());
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine->qmlEngine());
if (!ep)
return;
QQmlPropertyCapture *capture = ep->propertyCapture;
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index dd548168c3..e3955deee5 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -61,15 +61,41 @@ public:
typedef void (*ClearFunction)(QQmlListProperty<T> *);
QQmlListProperty()
- : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {}
+ : object(Q_NULLPTR),
+ data(Q_NULLPTR),
+ append(Q_NULLPTR),
+ count(Q_NULLPTR),
+ at(Q_NULLPTR),
+ clear(Q_NULLPTR),
+ dummy1(Q_NULLPTR),
+ dummy2(Q_NULLPTR)
+ {}
QQmlListProperty(QObject *o, QList<T *> &list)
: object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
- clear(qlist_clear), dummy1(0), dummy2(0) {}
+ clear(qlist_clear),
+ dummy1(Q_NULLPTR),
+ dummy2(Q_NULLPTR)
+ {}
QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
ClearFunction r )
- : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {}
+ : object(o),
+ data(d),
+ append(a),
+ count(c),
+ at(t),
+ clear(r),
+ dummy1(Q_NULLPTR),
+ dummy2(Q_NULLPTR)
+ {}
QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction t)
- : object(o), data(d), append(0), count(c), at(t), clear(0), dummy1(0), dummy2(0) {}
+ : object(o),
+ data(d),
+ append(Q_NULLPTR),
+ count(c), at(t),
+ clear(Q_NULLPTR),
+ dummy1(Q_NULLPTR),
+ dummy2(Q_NULLPTR)
+ {}
bool operator==(const QQmlListProperty &o) const {
return object == o.object &&
data == o.data &&
@@ -114,7 +140,7 @@ class Q_QML_EXPORT QQmlListReference
{
public:
QQmlListReference();
- QQmlListReference(QObject *, const char *property, QQmlEngine * = 0);
+ QQmlListReference(QObject *, const char *property, QQmlEngine * = Q_NULLPTR);
QQmlListReference(const QQmlListReference &);
QQmlListReference &operator=(const QQmlListReference &);
~QQmlListReference();
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 1a7896bde8..29fff04325 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -716,6 +716,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QQmlTypeNameCache::Result res = context->imports->query(stringAt(binding->propertyNameIndex));
if (res.isValid())
attachedType = res.type;
+ else
+ return false;
}
const int id = attachedType->attachedPropertiesId(QQmlEnginePrivate::get(engine));
QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject);
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 357b5ae577..3be52cf461 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -698,7 +698,6 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
if (accessorProperty) {
data->flags |= QQmlPropertyData::HasAccessors;
data->accessors = accessorProperty->accessors;
- data->accessorData = accessorProperty->data;
} else if (old) {
data->markAsOverrideOf(old);
}
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 0b3573c58c..4ff5ee89f9 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -209,7 +209,6 @@ public:
};
struct { // When HasAccessors
QQmlAccessors *accessors;
- qintptr accessorData;
};
};
int coreIndex;
diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
index 0c639b140d..f9872a6ad4 100644
--- a/src/qml/types/qqmllistmodelworkeragent_p.h
+++ b/src/qml/types/qqmllistmodelworkeragent_p.h
@@ -97,7 +97,8 @@ public:
VariantRef &operator=(const VariantRef &o) {
if (o.a) o.a->addref();
- if (a) a->release(); a = o.a;
+ if (a) a->release();
+ a = o.a;
return *this;
}
diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h
index ea1561bc60..01048f3662 100644
--- a/src/qml/util/qqmlpropertymap.h
+++ b/src/qml/util/qqmlpropertymap.h
@@ -55,7 +55,7 @@ class Q_QML_EXPORT QQmlPropertyMap : public QObject
{
Q_OBJECT
public:
- explicit QQmlPropertyMap(QObject *parent = 0);
+ explicit QQmlPropertyMap(QObject *parent = Q_NULLPTR);
virtual ~QQmlPropertyMap();
QVariant value(const QString &key) const;