aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-01-06 16:12:40 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-01-06 16:12:41 +0100
commit24e2b39e7a06687322a18a158a083eb51a7c0dca (patch)
tree1a32caf6dd6db74fbac9553a094bb00b216fa678 /src/qml
parent39540124dd0900e0c99dcda8c0ebdf4f3cea8d5e (diff)
parentdaff5f2988cef31442629a48c3b3088abf01837a (diff)
Merge remote-tracking branch 'origin/stable' into dev
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp67
-rw-r--r--src/qml/compiler/qv4ssa.cpp300
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/doc/src/cppintegration/exposecppattributes.qdoc2
-rw-r--r--src/qml/doc/src/javascript/qmlglobalobject.qdoc2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc5
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/scope.qdoc5
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/structure.qdoc4
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc5
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/topic.qdoc6
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/imports.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/signals.qdoc2
-rw-r--r--src/qml/doc/src/whatsnew.qdoc6
-rw-r--r--src/qml/jsapi/qjsvalue.cpp2
-rw-r--r--src/qml/qml.pro2
-rw-r--r--src/qml/qml/qqmlcompiler.cpp5
-rw-r--r--src/qml/qml/qqmlcomponent.cpp28
-rw-r--r--src/qml/qml/qqmlfileselector.cpp2
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp4
19 files changed, 241 insertions, 210 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 8809221abe..13b23fde68 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1347,38 +1347,29 @@ static V4IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, V4IR::MemberExpre
V4IR::Type result = V4IR::VarType;
QQmlType *type = static_cast<QQmlType*>(resolver->data);
- if (type->isSingleton()) {
- if (type->isCompositeSingleton()) {
- QQmlTypeData *tdata = qmlEngine->typeLoader.getType(type->singletonInstanceInfo()->url);
- Q_ASSERT(tdata);
- Q_ASSERT(tdata->isComplete());
- initMetaObjectResolver(resolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId));
- resolver->flags |= AllPropertiesAreFinal;
- } else {
- const QMetaObject *singletonMo = type->singletonInstanceInfo()->instanceMetaObject;
- if (!singletonMo) { // We can only accelerate C++ singletons that were registered with their meta-type
- resolver->clear();
- return result;
- }
- initMetaObjectResolver(resolver, qmlEngine->cache(singletonMo));
- resolver->flags |= LookupsIncludeEnums;
+
+ if (member->name->constData()->isUpper()) {
+ bool ok = false;
+ int value = type->enumValue(*member->name, &ok);
+ if (ok) {
+ member->setEnumValue(value);
+ resolver->clear();
+ return V4IR::SInt32Type;
}
+ }
+
+ if (type->isCompositeSingleton()) {
+ QQmlTypeData *tdata = qmlEngine->typeLoader.getType(type->singletonInstanceInfo()->url);
+ Q_ASSERT(tdata);
+ Q_ASSERT(tdata->isComplete());
+ initMetaObjectResolver(resolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId));
+ resolver->flags |= AllPropertiesAreFinal;
+ return resolver->resolveMember(qmlEngine, resolver, member);
+ } else if (const QMetaObject *attachedMeta = type->attachedPropertiesType()) {
+ QQmlPropertyCache *cache = qmlEngine->cache(attachedMeta);
+ initMetaObjectResolver(resolver, cache);
+ member->setAttachedPropertiesId(type->attachedPropertiesId());
return resolver->resolveMember(qmlEngine, resolver, member);
- } else {
- if (member->name->constData()->isUpper()) {
- bool ok = false;
- int value = type->enumValue(*member->name, &ok);
- if (ok) {
- member->setEnumValue(value);
- resolver->clear();
- return V4IR::SInt32Type;
- }
- } else if (const QMetaObject *attachedMeta = type->attachedPropertiesType()) {
- QQmlPropertyCache *cache = qmlEngine->cache(attachedMeta);
- initMetaObjectResolver(resolver, cache);
- member->setAttachedPropertiesId(type->attachedPropertiesId());
- return resolver->resolveMember(qmlEngine, resolver, member);
- }
}
resolver->clear();
@@ -1559,8 +1550,10 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
V4IR::Temp *result = _block->TEMP(_block->newTemp());
_block->MOVE(result, s);
result = _block->TEMP(result->index);
- initMetaObjectResolver(&result->memberResolver, mapping.type);
- result->memberResolver.flags |= AllPropertiesAreFinal;
+ if (mapping.type) {
+ initMetaObjectResolver(&result->memberResolver, mapping.type);
+ result->memberResolver.flags |= AllPropertiesAreFinal;
+ }
result->isReadOnly = true; // don't allow use as lvalue
return result;
}
@@ -1573,14 +1566,14 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
} else if (r.type) {
V4IR::Name *typeName = _block->NAME(name, line, col);
// Make sure the run-time loads this through the more efficient singleton getter.
- typeName->qmlSingleton = r.type->isSingleton();
+ typeName->qmlSingleton = r.type->isCompositeSingleton();
typeName->freeOfSideEffects = true;
-
V4IR::Temp *result = _block->TEMP(_block->newTemp());
- initQmlTypeResolver(&result->memberResolver, r.type);
-
_block->MOVE(result, typeName);
- return _block->TEMP(result->index);
+
+ result = _block->TEMP(result->index);
+ initQmlTypeResolver(&result->memberResolver, r.type);
+ return result;
} else {
Q_ASSERT(r.importNamespace);
V4IR::Name *namespaceName = _block->NAME(name, line, col);
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index eccdfff623..679cf1b3a7 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -39,6 +39,10 @@
**
****************************************************************************/
+#ifndef QT_NO_DEBUG
+# define _LIBCPP_DEBUG2 0
+#endif // QT_NO_DEBUG
+
#include "qv4ssa_p.h"
#include "qv4isel_util_p.h"
#include "qv4util_p.h"
@@ -256,71 +260,88 @@ inline Temp *unescapableTemp(Expr *e, bool variablesCanEscape)
}
class DominatorTree {
+ typedef int BasicBlockIndex;
+ enum { InvalidBasicBlockIndex = -1 };
+
+ const QVector<BasicBlock *> nodes;
int N;
- QHash<BasicBlock *, int> dfnum;
- QVector<BasicBlock *> vertex;
- QHash<BasicBlock *, BasicBlock *> parent;
- QHash<BasicBlock *, BasicBlock *> ancestor;
- QHash<BasicBlock *, BasicBlock *> best;
- QHash<BasicBlock *, BasicBlock *> semi;
- QHash<BasicBlock *, BasicBlock *> idom;
- QHash<BasicBlock *, BasicBlock *> samedom;
- QHash<BasicBlock *, QSet<BasicBlock *> > bucket;
+ std::vector<int> dfnum; // BasicBlock index -> dfnum
+ std::vector<int> vertex;
+ std::vector<BasicBlockIndex> parent; // BasicBlock index -> parent BasicBlock index
+ std::vector<BasicBlockIndex> ancestor; // BasicBlock index -> ancestor BasicBlock index
+ std::vector<BasicBlockIndex> best; // BasicBlock index -> best BasicBlock index
+ std::vector<BasicBlockIndex> semi; // BasicBlock index -> semi dominator BasicBlock index
+ std::vector<BasicBlockIndex> idom; // BasicBlock index -> immediate dominator BasicBlock index
+ std::vector<BasicBlockIndex> samedom; // BasicBlock index -> same dominator BasicBlock index
+ std::vector<QSet<BasicBlock *> > DF; // BasicBlock index -> dominator frontier
struct DFSTodo {
- BasicBlock *node, *parent;
+ BasicBlockIndex node, parent;
+
+ DFSTodo()
+ : node(InvalidBasicBlockIndex)
+ , parent(InvalidBasicBlockIndex)
+ {}
- DFSTodo():node(0),parent(0){}
- DFSTodo(BasicBlock *node, BasicBlock *parent):node(node),parent(parent){}
+ DFSTodo(BasicBlockIndex node, BasicBlockIndex parent)
+ : node(node)
+ , parent(parent)
+ {}
};
- void DFS(BasicBlock *node) {
- QVector<DFSTodo> worklist;
- worklist.reserve(vertex.capacity());
- DFSTodo todo(node, 0);
+ void DFS(BasicBlockIndex node) {
+ std::vector<DFSTodo> worklist;
+ worklist.reserve(vertex.capacity() / 2);
+ DFSTodo todo(node, InvalidBasicBlockIndex);
while (true) {
- BasicBlock *n = todo.node;
+ BasicBlockIndex n = todo.node;
if (dfnum[n] == 0) {
dfnum[n] = N;
vertex[N] = n;
parent[n] = todo.parent;
++N;
- for (int i = n->out.size() - 1; i > 0; --i)
- worklist.append(DFSTodo(n->out[i], n));
+ const QVector<BasicBlock *> &out = nodes[n]->out;
+ for (int i = out.size() - 1; i > 0; --i)
+ worklist.push_back(DFSTodo(out[i]->index, n));
- if (n->out.size() > 0) {
- todo.node = n->out.first();
+ if (out.size() > 0) {
+ todo.node = out.first()->index;
todo.parent = n;
continue;
}
}
- if (worklist.isEmpty())
+ if (worklist.empty())
break;
- todo = worklist.last();
- worklist.removeLast();
+ todo = worklist.back();
+ worklist.pop_back();
}
+
+#if defined(SHOW_SSA)
+ for (int i = 0; i < nodes.size(); ++i)
+ qDebug("\tL%d: dfnum = %d, parent = %d", i, dfnum[i], parent[i]);
+#endif // SHOW_SSA
}
- BasicBlock *ancestorWithLowestSemi(BasicBlock *v) {
- QVector<BasicBlock *> worklist;
- worklist.reserve(vertex.capacity());
- for (BasicBlock *it = v; it; it = ancestor[it])
- worklist.append(it);
+ BasicBlockIndex ancestorWithLowestSemi(BasicBlockIndex v) {
+ std::vector<BasicBlockIndex> worklist;
+ worklist.reserve(vertex.capacity() / 2);
+ for (BasicBlockIndex it = v; it != InvalidBasicBlockIndex; it = ancestor[it])
+ worklist.push_back(it);
if (worklist.size() < 2)
return best[v];
- BasicBlock *b = 0;
- BasicBlock *last = worklist.last();
+ BasicBlockIndex b = InvalidBasicBlockIndex;
+ BasicBlockIndex last = worklist.back();
for (int it = worklist.size() - 2; it >= 0; --it) {
- BasicBlock *bbIt = worklist[it];
+ BasicBlockIndex bbIt = worklist[it];
ancestor[bbIt] = last;
- BasicBlock *&best_it = best[bbIt];
- if (b && dfnum[semi[b]] < dfnum[semi[best_it]])
+ BasicBlockIndex &best_it = best[bbIt];
+ if (b != InvalidBasicBlockIndex && dfnum[semi[b]] < dfnum[semi[best_it]])
best_it = b;
else
b = best_it;
@@ -328,66 +349,82 @@ class DominatorTree {
return b;
}
- void link(BasicBlock *p, BasicBlock *n) {
+ void link(BasicBlockIndex p, BasicBlockIndex n) {
ancestor[n] = p;
best[n] = n;
}
- void calculateIDoms(const QVector<BasicBlock *> &nodes) {
+ void calculateIDoms() {
Q_ASSERT(nodes.first()->in.isEmpty());
- vertex.resize(nodes.size());
- foreach (BasicBlock *n, nodes) {
- dfnum[n] = 0;
- semi[n] = 0;
- ancestor[n] = 0;
- idom[n] = 0;
- samedom[n] = 0;
- }
- DFS(nodes.first());
+ vertex = std::vector<int>(nodes.size(), InvalidBasicBlockIndex);
+ parent = std::vector<int>(nodes.size(), InvalidBasicBlockIndex);
+ dfnum = std::vector<int>(nodes.size(), 0);
+ semi = std::vector<BasicBlockIndex>(nodes.size(), InvalidBasicBlockIndex);
+ ancestor = std::vector<BasicBlockIndex>(nodes.size(), InvalidBasicBlockIndex);
+ idom = std::vector<BasicBlockIndex>(nodes.size(), InvalidBasicBlockIndex);
+ samedom = std::vector<BasicBlockIndex>(nodes.size(), InvalidBasicBlockIndex);
+ best = std::vector<BasicBlockIndex>(nodes.size(), InvalidBasicBlockIndex);
+
+ QHash<BasicBlockIndex, std::vector<BasicBlockIndex> > bucket;
+
+ DFS(nodes.first()->index);
Q_ASSERT(N == nodes.size()); // fails with unreachable nodes, but those should have been removed before.
for (int i = N - 1; i > 0; --i) {
- BasicBlock *n = vertex[i];
- BasicBlock *p = parent[n];
- BasicBlock *s = p;
-
- foreach (BasicBlock *v, n->in) {
- BasicBlock *ss;
- if (dfnum[v] <= dfnum[n])
- ss = v;
+ BasicBlockIndex n = vertex[i];
+ BasicBlockIndex p = parent[n];
+ BasicBlockIndex s = p;
+
+ foreach (BasicBlock *v, nodes.at(n)->in) {
+ BasicBlockIndex ss = InvalidBasicBlockIndex;
+ if (dfnum[v->index] <= dfnum[n])
+ ss = v->index;
else
- ss = semi[ancestorWithLowestSemi(v)];
+ ss = semi[ancestorWithLowestSemi(v->index)];
if (dfnum[ss] < dfnum[s])
s = ss;
}
semi[n] = s;
- bucket[s].insert(n);
+ bucket[s].push_back(n);
link(p, n);
- foreach (BasicBlock *v, bucket[p]) {
- BasicBlock *y = ancestorWithLowestSemi(v);
- BasicBlock *semi_v = semi[v];
- if (semi[y] == semi_v)
- idom[v] = semi_v;
- else
- samedom[v] = y;
+ if (bucket.contains(p)) {
+ foreach (BasicBlockIndex v, bucket[p]) {
+ BasicBlockIndex y = ancestorWithLowestSemi(v);
+ BasicBlockIndex semi_v = semi[v];
+ if (semi[y] == semi_v)
+ idom[v] = semi_v;
+ else
+ samedom[v] = y;
+ }
+ bucket.remove(p);
}
- bucket[p].clear();
}
+
+#if defined(SHOW_SSA)
+ for (int i = 0; i < nodes.size(); ++i)
+ qDebug("\tL%d: ancestor = %d, semi = %d, samedom = %d", i, ancestor[i], semi[i], samedom[i]);
+#endif // SHOW_SSA
+
for (int i = 1; i < N; ++i) {
- BasicBlock *n = vertex[i];
- Q_ASSERT(ancestor[n] && ((semi[n] && dfnum[ancestor[n]] <= dfnum[semi[n]]) || semi[n] == n));
- Q_ASSERT(bucket[n].isEmpty());
- if (BasicBlock *sdn = samedom[n])
+ BasicBlockIndex n = vertex[i];
+ Q_ASSERT(n != InvalidBasicBlockIndex);
+ Q_ASSERT(!bucket.contains(n));
+ Q_ASSERT(ancestor[n] != InvalidBasicBlockIndex
+ && ((semi[n] != InvalidBasicBlockIndex
+ && dfnum[ancestor[n]] <= dfnum[semi[n]]) || semi[n] == n));
+ BasicBlockIndex sdn = samedom[n];
+ if (sdn != InvalidBasicBlockIndex)
idom[n] = idom[sdn];
}
-#ifdef SHOW_SSA
+#if defined(SHOW_SSA)
qout << "Immediate dominators:" << endl;
foreach (BasicBlock *to, nodes) {
qout << '\t';
- if (BasicBlock *from = idom.value(to))
- qout << from->index;
+ BasicBlockIndex from = idom.at(to->index);
+ if (from != InvalidBasicBlockIndex)
+ qout << from;
else
qout << "(none)";
qout << " -> " << to->index << endl;
@@ -396,55 +433,72 @@ class DominatorTree {
}
struct NodeProgress {
- QSet<BasicBlock *> children;
- QSet<BasicBlock *> todo;
+ std::vector<BasicBlockIndex> children;
+ std::vector<BasicBlockIndex> todo;
};
- void computeDF(const QVector<BasicBlock *> &nodes) {
- QHash<BasicBlock *, NodeProgress> nodeStatus;
+ void computeDF() {
+ // compute children of each node in the dominator tree
+ std::vector<std::vector<BasicBlockIndex> > children; // BasicBlock index -> children
+ children.resize(nodes.size());
+ foreach (BasicBlock *n, nodes) {
+ const BasicBlockIndex nodeIndex = n->index;
+ Q_ASSERT(nodes.at(nodeIndex) == n);
+ const BasicBlockIndex nodeDominator = idom[nodeIndex];
+ if (nodeDominator == InvalidBasicBlockIndex)
+ continue; // there is no dominator to add this node to as a child (e.g. the start node)
+ children[nodeDominator].push_back(nodeIndex);
+ }
+
+ // Fill the worklist and initialize the node status for each basic-block
+ QHash<BasicBlockIndex, NodeProgress> nodeStatus;
nodeStatus.reserve(nodes.size());
- QVector<BasicBlock *> worklist;
+ std::vector<BasicBlockIndex> worklist;
worklist.reserve(nodes.size() * 2);
for (int i = 0, ei = nodes.size(); i != ei; ++i) {
- BasicBlock *node = nodes[i];
- worklist.append(node);
- NodeProgress &np = nodeStatus[node];
- np.children = children[node];
- np.todo = children[node];
+ BasicBlockIndex nodeIndex = nodes[i]->index;
+ worklist.push_back(nodeIndex);
+ NodeProgress &np = nodeStatus[nodeIndex];
+ np.children = children[nodeIndex];
+ np.todo = children[nodeIndex];
}
- while (!worklist.isEmpty()) {
- BasicBlock *node = worklist.last();
+ std::vector<bool> DF_done(nodes.size(), false);
+
+ while (!worklist.empty()) {
+ BasicBlockIndex node = worklist.back();
- if (DF.contains(node)) {
- worklist.removeLast();
+ if (DF_done[node]) {
+ worklist.pop_back();
continue;
}
NodeProgress &np = nodeStatus[node];
- QSet<BasicBlock *>::iterator it = np.todo.begin();
+ std::vector<BasicBlockIndex>::iterator it = np.todo.begin();
while (it != np.todo.end()) {
- if (DF.contains(*it)) {
+ if (DF_done[*it]) {
it = np.todo.erase(it);
} else {
- worklist.append(*it);
+ worklist.push_back(*it);
break;
}
}
- if (np.todo.isEmpty()) {
+ if (np.todo.empty()) {
QSet<BasicBlock *> S;
- foreach (BasicBlock *y, node->out)
- if (idom[y] != node)
- if (!S.contains(y))
- S.insert(y);
- foreach (BasicBlock *child, np.children)
- foreach (BasicBlock *w, DF[child])
- if (!dominates(node, w) || node == w)
- if (!S.contains(w))
- S.insert(w);
- DF.insert(node, S);
- worklist.removeLast();
+ foreach (BasicBlock *y, nodes[node]->out)
+ if (idom[y->index] != node)
+ S.insert(y);
+ foreach (BasicBlockIndex child, np.children) {
+ foreach (BasicBlock *w, DF[child]) {
+ const BasicBlockIndex wIndex = w->index;
+ if (node == wIndex || !dominates(node, w->index))
+ S.insert(w);
+ }
+ }
+ DF[node] = S;
+ DF_done[node] = true;
+ worklist.pop_back();
}
}
@@ -452,7 +506,7 @@ class DominatorTree {
qout << "Dominator Frontiers:" << endl;
foreach (BasicBlock *n, nodes) {
qout << "\tDF[" << n->index << "]: {";
- QList<BasicBlock *> SList = DF[n].values();
+ QList<BasicBlock *> SList = DF[n->index].values();
for (int i = 0; i < SList.size(); ++i) {
if (i > 0)
qout << ", ";
@@ -463,7 +517,7 @@ class DominatorTree {
#endif // SHOW_SSA
#if !defined(QT_NO_DEBUG) && defined(CAN_TAKE_LOSTS_OF_TIME)
foreach (BasicBlock *n, nodes) {
- foreach (BasicBlock *fBlock, DF[n]) {
+ foreach (BasicBlock *fBlock, DF[n->index]) {
Q_ASSERT(!dominates(n, fBlock) || fBlock == n);
bool hasDominatedSucc = false;
foreach (BasicBlock *succ, fBlock->in) {
@@ -473,7 +527,7 @@ class DominatorTree {
}
}
if (!hasDominatedSucc) {
- qout << fBlock->index << " in DF[" << n->index << "] has no dominated predecessors" << endl;
+ qout << fBlock << " in DF[" << n->index << "] has no dominated predecessors" << endl;
}
Q_ASSERT(hasDominatedSucc);
}
@@ -481,35 +535,33 @@ class DominatorTree {
#endif // !QT_NO_DEBUG
}
- QHash<BasicBlock *, QSet<BasicBlock *> > children;
- QHash<BasicBlock *, QSet<BasicBlock *> > DF;
-
public:
DominatorTree(const QVector<BasicBlock *> &nodes)
- : N(0)
+ : nodes(nodes)
+ , N(0)
{
- calculateIDoms(nodes);
-
- // compute children of n
- foreach (BasicBlock *n, nodes) {
- QSet<BasicBlock *> &c = children[idom[n]];
- if (!c.contains(n))
- c.insert(n);
- }
-
- computeDF(nodes);
+ DF.resize(nodes.size());
+ calculateIDoms();
+ computeDF();
}
QSet<BasicBlock *> operator[](BasicBlock *n) const {
- return DF[n];
+ return DF[n->index];
}
BasicBlock *immediateDominator(BasicBlock *bb) const {
- return idom[bb];
+ return nodes[idom[bb->index]];
}
bool dominates(BasicBlock *dominator, BasicBlock *dominated) const {
- for (BasicBlock *it = dominated; it; it = idom[it]) {
+ // The index of the basic blocks might have changed, or the nodes array might have changed,
+ // or the block got deleted, so get the index from our copy of the array.
+ return dominates(nodes.indexOf(dominator), nodes.indexOf(dominated));
+ }
+
+private:
+ bool dominates(BasicBlockIndex dominator, BasicBlockIndex dominated) const {
+ for (BasicBlockIndex it = dominated; it != InvalidBasicBlockIndex; it = idom[it]) {
if (it == dominator)
return true;
}
@@ -1581,7 +1633,8 @@ public:
BasicBlock *bb = function->basicBlocks[i];
if (i == 0 || !bb->in.isEmpty())
foreach (Stmt *s, bb->statements)
- _worklist.insert(s);
+ if (!s->asJump())
+ _worklist.insert(s);
}
while (!_worklist.isEmpty()) {
@@ -2687,6 +2740,11 @@ namespace {
/// Important: this assumes that there are no critical edges in the control-flow graph!
void purgeBB(BasicBlock *bb, Function *func, DefUsesCalculator &defUses, QVector<Stmt *> &W)
{
+ // TODO: change this to mark the block as deleted, but leave it alone so that other references
+ // won't be dangling pointers.
+ // TODO: after the change above: if we keep on detaching the block from predecessors or
+ // successors, update the DominatorTree too.
+
// don't purge blocks that are entry points for catch statements. They might not be directly
// connected, but are required anyway
if (bb->isExceptionHandler)
@@ -2826,6 +2884,8 @@ void optimizeSSA(Function *function, DefUsesCalculator &defUses)
foreach (BasicBlock *bb, function->basicBlocks) {
for (int i = 0, ei = bb->statements.size(); i != ei; ++i) {
Stmt **s = &bb->statements[i];
+ if ((*s)->asJump())
+ continue; // nothing do do there
W.append(*s);
ref.insert(*s, s);
}
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 74aaae7724..43dbe2525c 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -34,7 +34,7 @@ qhp.QtQml.subprojects.qmltypes.sortPages = true
tagfile = ../../../doc/qtqml/qtqml.tags
-depends += qtcore qtxmlpatterns qtgui qtquick qtdoc
+depends += qtcore qtxmlpatterns qtgui qtquick qtdoc qtlinguist
headerdirs += .. \
../../imports/models
diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
index d3662fb210..5d70cb5174 100644
--- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
+++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
@@ -477,7 +477,7 @@ MessageBoard {
As with property values and method parameters, a signal parameter must have a
type that is supported by the QML engine; see
-\l {Semantics of Data Transfer from C++ to QML}. (Using an
+\l {Data Type Conversion Between QML and C++}. (Using an
unregistered type will not generate an error, but the parameter value will
not be accessible from the handler.)
diff --git a/src/qml/doc/src/javascript/qmlglobalobject.qdoc b/src/qml/doc/src/javascript/qmlglobalobject.qdoc
index cbffcddb7b..4329bbb351 100644
--- a/src/qml/doc/src/javascript/qmlglobalobject.qdoc
+++ b/src/qml/doc/src/javascript/qmlglobalobject.qdoc
@@ -38,7 +38,7 @@ additional imports:
\li The \l{QmlGlobalQtObject}{Qt object}: This object is specific to QML, and provides helper methods
and properties specific to the QML environment.
\li qsTr(), qsTranslate(), qsTrId(), QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRID_NOOP() functions:
- These functions are specific to QML, and provide \l{Translation}{translation capabilities} to the QML environment.
+ These functions are specific to QML, and provide \l{Overview of the Translation Process}{translation capabilities} to the QML environment.
\li gc() function: This function is specific to QML, and provides a way to manually trigger garbage collection.
\li print() function: This function is specific to QML, and provides a simple way to output information to the console.
\li The \l{Console API}{console object}: This object implements a subset of the \l{http://getfirebug.com/wiki/index.php/Console_API}{FireBug Console API}.
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 679f7bac96..19cd3b3f02 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -42,7 +42,8 @@
specified \a Flags.
Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which
- declares that the \a Type supports \l {Attached Properties}.
+ declares that the \a Type supports \l {Attached Properties and Attached Signal Handlers}
+ {attached properties}.
#include <QtQml> to use this macro.
*/
@@ -51,7 +52,7 @@
\fn void qmlClearTypeRegistrations()
\relates QQmlEngine
- Clears all stored type registrations, such as those produced with \l qmlRegisterType.
+ Clears all stored type registrations, such as those produced with \l qmlRegisterType().
Do not call this function while a QQmlEngine exists or behavior will be undefined.
Any existing QQmlEngines must be deleted before calling this function. This function
diff --git a/src/qml/doc/src/qmllanguageref/documents/scope.qdoc b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc
index 870eb21a07..845ca30b4f 100644
--- a/src/qml/doc/src/qmllanguageref/documents/scope.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc
@@ -79,7 +79,7 @@ with local variables declared in another.
\l {QML Documents} include import statements that define the type names
and JavaScript files visible to the document. In addition to their use in the
QML declaration itself, type names are used by JavaScript code when accessing
-\l {Attached Properties} and enumeration values.
+\l {Attached Properties and Attached Signal Handlers}{attached properties} and enumeration values.
The effect of an import applies to every property binding, and JavaScript
function in the QML document, even those in nested inline components. The
@@ -123,7 +123,8 @@ directly, without needing any form of object prefix. QML introduces a more
structured, object-oriented approach to JavaScript, and consequently does not
require the use of the JavaScript \c this property.
-Care must be used when accessing \l {Attached Properties} from bindings due
+Care must be used when accessing \l {Attached Properties and Attached Signal Handlers}
+{attached properties} from bindings due
to their interaction with the scope object. Conceptually attached properties
exist on \e all objects, even if they only have an effect on a subset of those.
Consequently unqualified attached property reads will always resolve to an
diff --git a/src/qml/doc/src/qmllanguageref/documents/structure.qdoc b/src/qml/doc/src/qmllanguageref/documents/structure.qdoc
index c8176f7e0f..e526e47b00 100644
--- a/src/qml/doc/src/qmllanguageref/documents/structure.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/structure.qdoc
@@ -57,8 +57,8 @@ presentation to the \l{QQmlEngine}{QML engine}, unlike C or C++.
The \c import statements do not copy and prepend the code in the document, but
instead instruct the QML engine on how to resolve type references found
in the document. Any type reference present in a QML document - such as \c
-Rectangle and \c ListView - including those made within an \l {Inline
-JavaScript}{JavaScript block} or \l {Property Binding}{property
+Rectangle and \c ListView - including those made within a \l {JavaScript
+Expressions in QML Documents}{JavaScript block} or \l {Property Binding}{property
bindings}, are \e resolved based exclusively on the import statements. At least
one \c import statement must be present such as \c{import QtQuick 2.0}.
diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
index 57d54e27e0..c89d4a3c0d 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
@@ -62,7 +62,7 @@ module <ModuleIdentifier>
The <ModuleIdentifier> is the (dotted URI notation) identifier
for the module, which must match the module's install path.
- The \l{qtqml-modules-topic.html#the-module-identifier-directive}
+ The \l{Identified Modules#Semantics of Identified Modules}
{module identifier directive} must be the first line of the file.
Exactly one module identifier directive may exist in the \c qmldir
file.
@@ -113,7 +113,8 @@ internal MyPrivateType MyPrivateType.qml
\endcode
This is necessary if the module may be imported remotely (see
- \l{Remotely Installed Modules}) because if an exported type depends
+ \l{Identified Modules#Remotely Installed Identified Modules}
+ {Remotely Installed Identified Modules}) because if an exported type depends
on an non-exported type within the module, the engine must also
load the non-exported type.
diff --git a/src/qml/doc/src/qmllanguageref/modules/topic.qdoc b/src/qml/doc/src/qmllanguageref/modules/topic.qdoc
index 597e7b7ca3..9d4173a883 100644
--- a/src/qml/doc/src/qmllanguageref/modules/topic.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/topic.qdoc
@@ -64,15 +64,15 @@ The directory can then be installed into the
\l{qtqml-syntax-imports.html#qml-import-path}{QML import path} as a module.
Note that defining a module is not the only way to share common QML types
-within a project - a simple \l{qtqml-syntax-imports.html#directory-import}
+within a project - a simple \l{Importing QML Document Directories}
{QML document directory import} may also be used for this purpose.
\section1 Supported QML Module Types
There are two different types of modules supported by QML:
\list
-\li \l{qtqml-modules-identifiedmodules.html}{Identified Modules}
-\li \l{qtqml-modules-legacymodules.html}{Legacy Modules} (deprecated)
+\li \l{Identified Modules}
+\li \l{Legacy Modules} (deprecated)
\endlist
Identified modules explicitly define their identifier and are installed into
diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
index 1496a1e5c9..0939a460fe 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc
@@ -281,7 +281,7 @@ JavaScript resources, please see the in-depth documentation about
\section1 QML Import Path
-When an \l{qtqml-modules-installedmodules.html}{installed module} is imported,
+When an \l{Identified Modules}{identified module} is imported,
the QML engine searches the \e{import path} for a matching module.
This import path, as returned by QQmlEngine::importPathList(), defines the
diff --git a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
index 6344d16caa..b9f391e4dc 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
@@ -142,7 +142,7 @@ Rectangle {
\section2 Attached Signal Handlers
-An \l {attached signal handler} is a signal handler that receives a signal from an \e {attaching type} rather than the object within which the handler is declared.
+An \l {Attached Properties and Attached Signal Handlers}{attached signal handler} is a signal handler that receives a signal from an \e {attaching type} rather than the object within which the handler is declared.
For example, \c \l {Component::isCompleted}{Component.isCompleted} is an attached signal handler. This handler is often used to execute some JavaScript code when its creation process has been completed, as in the example below:
diff --git a/src/qml/doc/src/whatsnew.qdoc b/src/qml/doc/src/whatsnew.qdoc
index a0e5202174..f13a4dac1d 100644
--- a/src/qml/doc/src/whatsnew.qdoc
+++ b/src/qml/doc/src/whatsnew.qdoc
@@ -36,10 +36,10 @@ a summary of the new changes:
\list
\li New QQmlApplicationEngine convenience class for QML applications.
\li New Instantiatior type for generic, dynamic object creation.
-\li New properties for \l Qt.application: arguments, name, and version.
+\li New properties for \l {Qt::application}{Qt.application}: arguments, name, and version.
\li The 'with' statement has been deprecated and is slated for removal in a
future version of the language.
-\li New \l Qt.platform object with an os property
+\li New \l {Qt::platform}{Qt.platform} object with an \c os property
\li New \l qmlClearTypeRegistrations() function drops all data from qmlRegisterType() calls
\li New \l qmlRegisterType() function for registering composite types.
\endlist
@@ -48,7 +48,7 @@ a summary of the new changes:
The \l{Qt QML Models QML Types}{Qt QML Models} is a new submodule in Qt 5.1 and
provides several QML types for handling data with models and lists. These types
-replace types such as \l VisualItem, \l VisualDataModel, and \l VisualDataGroup.
+replace types such as \l VisualItemModel, \l VisualDataModel, and \l VisualDataGroup.
\list
\li \l{Qt QML Models QML Types}{Models}
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index d7a1cef3ba..6a0cf0cf6d 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -1089,8 +1089,6 @@ QDateTime QJSValue::toDateTime() const
/*!
Returns true if this QJSValue is an object of the Date class;
otherwise returns false.
-
- \sa QJSEngine::newDate()
*/
bool QJSValue::isDate() const
{
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index d060b2d8c8..d0f655609e 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -19,7 +19,9 @@ exists("qqml_enable_gcov") {
QMAKE_DOCS = $$PWD/doc/qtqml.qdocconf
# 2415: variable "xx" of static storage duration was declared but never referenced
+# unused variable 'xx' [-Werror,-Wunused-const-variable]
intel_icc: WERROR += -ww2415
+clang: WERROR += -Wno-error=unused-const-variable
load(qt_module)
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index f07d4bb703..6717c97d88 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -3711,7 +3711,10 @@ bool QQmlCompiler::completeComponentBuild()
JSCodeGen::IdMapping m;
m.name = o->id;
m.idIndex = o->idIndex;
- m.type = o->metatype;
+ if (output->types[o->type].isFullyDynamicType)
+ m.type = 0;
+ else
+ m.type = o->metatype;
idMapping << m;
}
}
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 4a71c1a7e0..21bcd3569c 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -103,34 +103,6 @@ public:
};
V8_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
-/*
- Try to do what's necessary for a reasonable display of the type
- name, but no more (just enough for the client to do more extensive cleanup).
-
- Should only be called when debugging is enabled.
-*/
-static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
-{
- static const QString qmlMarker(QLatin1String("_QML"));
- static const QChar underscore(QLatin1Char('_'));
- static const QChar asterisk(QLatin1Char('*'));
- QQmlType *type = QQmlMetaType::qmlType(metaObject);
- QString typeName = type ? type->qmlTypeName() : QString::fromUtf8(metaObject->className());
- if (!type) {
- //### optimize further?
- int marker = typeName.indexOf(qmlMarker);
- if (marker != -1 && marker < typeName.count() - 1) {
- if (typeName[marker + 1] == underscore) {
- const QString className = typeName.left(marker) + asterisk;
- type = QQmlMetaType::qmlType(QMetaType::type(className.toUtf8()));
- if (type)
- typeName = type->qmlTypeName();
- }
- }
- }
- return typeName;
-}
-
/*!
\class QQmlComponent
\since 5.0
diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp
index 6ddc2eb2ff..a18b8327b1 100644
--- a/src/qml/qml/qqmlfileselector.cpp
+++ b/src/qml/qml/qqmlfileselector.cpp
@@ -92,7 +92,7 @@ Q_GLOBAL_STATIC(interceptorSelectorMap, interceptorInstances);
trigger this feature unless you have directories with such names inside your project.
If a new QQmlFileSelector is set on the engine, the old one will be replaced. Use
- \l QQmlFileSelector::get to query or use the existing instance.
+ \l QQmlFileSelector::get() to query or use the existing instance.
*/
/*!
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 41d5de0862..0409b92e89 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1157,7 +1157,7 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
is not present, or is not a valid ISO 3166 code, the most
appropriate country is chosen for the specified language.
- \sa QtQuick::Locale
+ \sa Locale
*/
ReturnedValue QtObject::method_locale(CallContext *ctx)
{
@@ -1801,7 +1801,7 @@ ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx)
Creating binary translation (QM) files suitable for use with this function requires passing
the \c -idbased option to the \c lrelease tool.
- \sa QT_TRID_NOOP, {Internationalization and Localization with Qt Quick}
+ \sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick}
*/
ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx)
{