diff --git a/src/libs/qmljs/parser/cmd.sed b/src/libs/qmljs/parser/cmd.sed
index fd76d634419d48063b2ff726048712bf0f0dbbe8..d76372675dca1b34b1fbadd7f98775938148824b 100644
--- a/src/libs/qmljs/parser/cmd.sed
+++ b/src/libs/qmljs/parser/cmd.sed
@@ -1,3 +1,4 @@
+s/private\/qdeclarative/qml/g
 s/qdeclarative/qml/g
 s/QDECLARATIVE/QML/g
 s/QDeclarative/Qml/g
diff --git a/src/libs/qmljs/parser/qmldirparser.cpp b/src/libs/qmljs/parser/qmldirparser.cpp
index 86ca9f6a60a231173713ecab3a61dfab099eeb63..6f2576f58b52cd2a6922c2c903d409cbe0055f95 100644
--- a/src/libs/qmljs/parser/qmldirparser.cpp
+++ b/src/libs/qmljs/parser/qmldirparser.cpp
@@ -170,10 +170,9 @@ bool QmlDirParser::parse()
             const int dotIndex = version.indexOf(QLatin1Char('.'));
 
             if (dotIndex == -1) {
-                qWarning() << "expected '.'"; // ### use reportError
+                reportError(lineNumber, -1, QLatin1String("expected '.'"));
             } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) {
-                qWarning() << "unexpected '.'"; // ### use reportError
-
+                reportError(lineNumber, -1, QLatin1String("unexpected '.'"));
             } else {
                 bool validVersionNumber = false;
                 const int majorVersion = version.left(dotIndex).toInt(&validVersionNumber);
@@ -189,8 +188,8 @@ bool QmlDirParser::parse()
                 }
             }
         } else {
-             // ### use reportError
-            qWarning() << "a component declaration requires 3 arguments, but" << (sectionCount + 1) << "were provided";
+            reportError(lineNumber, -1, 
+                        QString::fromUtf8("a component declaration requires 3 arguments, but %1 were provided").arg(sectionCount + 1));
         }
     }
 
diff --git a/src/libs/qmljs/parser/qmlerror.cpp b/src/libs/qmljs/parser/qmlerror.cpp
index fc4bcd512ac26e5f07da339d0e76aed3531251c3..d5363ab39745aed4ccdd997dad3edb37aad2b8b5 100644
--- a/src/libs/qmljs/parser/qmlerror.cpp
+++ b/src/libs/qmljs/parser/qmlerror.cpp
@@ -49,8 +49,27 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \class QmlError
-  \since 4.7
-    \brief The QmlError class encapsulates a QML error
+    \since 4.7
+    \brief The QmlError class encapsulates a QML error.
+
+    QmlError includes a textual description of the error, as well
+    as location information (the file, line, and column). The toString()
+    method creates a single-line, human-readable string containing all of
+    this information, for example:
+    \code
+    file:///home/user/test.qml:7:8: Invalid property assignment: double expected
+    \endcode
+
+    You can use qDebug() or qWarning() to output errors to the console. This method
+    will attempt to open the file indicated by the error
+    and include additional contextual information.
+    \code
+    file:///home/user/test.qml:7:8: Invalid property assignment: double expected
+            y: "hello"
+               ^
+    \endcode
+
+    \sa QmlView::errors(), QmlComponent::errors()
 */
 class QmlErrorPrivate
 {
@@ -69,7 +88,7 @@ QmlErrorPrivate::QmlErrorPrivate()
 }
 
 /*!
-    Create an empty error object.
+    Creates an empty error object.
 */
 QmlError::QmlError()
 : d(0)
@@ -77,7 +96,7 @@ QmlError::QmlError()
 }
 
 /*!
-    Create a copy of \a other.
+    Creates a copy of \a other.
 */
 QmlError::QmlError(const QmlError &other)
 : d(0)
@@ -86,7 +105,7 @@ QmlError::QmlError(const QmlError &other)
 }
 
 /*!
-    Assign \a other to this error object.
+    Assigns \a other to this error object.
 */
 QmlError &QmlError::operator=(const QmlError &other)
 {
@@ -112,7 +131,7 @@ QmlError::~QmlError()
 }
 
 /*!
-    Return true if this error is valid, otherwise false.
+    Returns true if this error is valid, otherwise false.
 */
 bool QmlError::isValid() const
 {
@@ -120,7 +139,7 @@ bool QmlError::isValid() const
 }
 
 /*!
-    Return the url for the file that caused this error.
+    Returns the url for the file that caused this error.
 */
 QUrl QmlError::url() const
 {
@@ -129,7 +148,7 @@ QUrl QmlError::url() const
 }
 
 /*!
-    Set the \a url for the file that caused this error.
+    Sets the \a url for the file that caused this error.
 */
 void QmlError::setUrl(const QUrl &url)
 {
@@ -138,7 +157,7 @@ void QmlError::setUrl(const QUrl &url)
 }
 
 /*!
-    Return the error description.
+    Returns the error description.
 */
 QString QmlError::description() const
 {
@@ -147,7 +166,7 @@ QString QmlError::description() const
 }
 
 /*!
-    Set the error \a description.
+    Sets the error \a description.
 */
 void QmlError::setDescription(const QString &description)
 {
@@ -156,7 +175,7 @@ void QmlError::setDescription(const QString &description)
 }
 
 /*!
-    Return the error line number.
+    Returns the error line number.
 */
 int QmlError::line() const
 {
@@ -165,7 +184,7 @@ int QmlError::line() const
 }
 
 /*!
-    Set the error \a line number.
+    Sets the error \a line number.
 */
 void QmlError::setLine(int line)
 {
@@ -174,7 +193,7 @@ void QmlError::setLine(int line)
 }
 
 /*!
-    Return the error column number.
+    Returns the error column number.
 */
 int QmlError::column() const
 {
@@ -183,7 +202,7 @@ int QmlError::column() const
 }
 
 /*!
-    Set the error \a column number.
+    Sets the error \a column number.
 */
 void QmlError::setColumn(int column)
 {
@@ -192,14 +211,20 @@ void QmlError::setColumn(int column)
 }
 
 /*!
-    Return the error as a human readable string.
+    Returns the error as a human readable string.
 */
 QString QmlError::toString() const
 {
     QString rv;
-    rv = url().toString() + QLatin1Char(':') + QString::number(line());
-    if(column() != -1) 
-        rv += QLatin1Char(':') + QString::number(column());
+    if (url().isEmpty()) {
+        rv = QLatin1String("<Unknown File>");
+    } else if (line() != -1) {
+        rv = url().toString() + QLatin1Char(':') + QString::number(line());
+        if(column() != -1) 
+            rv += QLatin1Char(':') + QString::number(column());
+    } else {
+        rv = url().toString();
+    }
 
     rv += QLatin1String(": ") + description();
 
@@ -210,7 +235,7 @@ QString QmlError::toString() const
     \relates QmlError
     \fn QDebug operator<<(QDebug debug, const QmlError &error)
 
-    Output a human readable version of \a error to \a debug.
+    Outputs a human readable version of \a error to \a debug.
 */
 
 QDebug operator<<(QDebug debug, const QmlError &error)
@@ -225,7 +250,9 @@ QDebug operator<<(QDebug debug, const QmlError &error)
         if (f.open(QIODevice::ReadOnly)) {
             QByteArray data = f.readAll();
             QTextStream stream(data, QIODevice::ReadOnly);
+#ifndef QT_NO_TEXTCODEC
             stream.setCodec("UTF-8");
+#endif
             const QString code = stream.readAll();
             const QStringList lines = code.split(QLatin1Char('\n'));
 
diff --git a/src/libs/qmljs/parser/qmljs.g b/src/libs/qmljs/parser/qmljs.g
index 86ddd6a29404a9eccee77a79bc111af974f68aa7..ee3ff565731c4500f3ea6fda860d70b6f185b632 100644
--- a/src/libs/qmljs/parser/qmljs.g
+++ b/src/libs/qmljs/parser/qmljs.g
@@ -1376,7 +1376,7 @@ case $rule_number: {
 } break;
 ./
 
-PropertyName: T_IDENTIFIER %prec REDUCE_HERE ;
+PropertyName: T_IDENTIFIER %prec SHIFT_THERE ;
 /.
 case $rule_number: {
   AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
diff --git a/src/libs/qmljs/parser/qmljsast_p.h b/src/libs/qmljs/parser/qmljsast_p.h
index 7bab8f80f6462e27acc7bdb84c2bd1694b8909ef..e6570eaf22cc2b8155ce4bd01ee6828dc4ddfc5e 100644
--- a/src/libs/qmljs/parser/qmljsast_p.h
+++ b/src/libs/qmljs/parser/qmljsast_p.h
@@ -224,6 +224,9 @@ public:
     inline Node()
         : kind(Kind_Undefined) {}
 
+    // NOTE: node destructors are never called,
+    //       instead we block free the memory
+    //       (see the NodePool class)
     virtual ~Node() {}
 
     virtual ExpressionNode *expressionCast();
@@ -247,7 +250,6 @@ class QML_PARSER_EXPORT ExpressionNode: public Node
 {
 public:
     ExpressionNode() {}
-    virtual ~ExpressionNode() {}
 
     virtual ExpressionNode *expressionCast();
 
@@ -259,7 +261,6 @@ class QML_PARSER_EXPORT Statement: public Node
 {
 public:
     Statement() {}
-    virtual ~Statement() {}
 
     virtual Statement *statementCast();
 
@@ -272,7 +273,7 @@ class QML_PARSER_EXPORT UiFormal: public Node
 public:
     QMLJS_DECLARE_AST_NODE(UiFormal)
 
-    explicit UiFormal(NameId *name, NameId *alias = 0)
+    UiFormal(NameId *name, NameId *alias = 0)
       : name(name), alias(alias)
     { }
 
@@ -379,7 +380,6 @@ public:
     QMLJS_DECLARE_AST_NODE(ThisExpression)
 
     ThisExpression() { kind = K; }
-    virtual ~ThisExpression() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -401,8 +401,6 @@ public:
     IdentifierExpression(NameId *n):
         name (n) { kind = K; }
 
-    virtual ~IdentifierExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -422,7 +420,6 @@ public:
     QMLJS_DECLARE_AST_NODE(NullExpression)
 
     NullExpression() { kind = K; }
-    virtual ~NullExpression() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -442,7 +439,6 @@ public:
     QMLJS_DECLARE_AST_NODE(TrueLiteral)
 
     TrueLiteral() { kind = K; }
-    virtual ~TrueLiteral() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -462,7 +458,6 @@ public:
     QMLJS_DECLARE_AST_NODE(FalseLiteral)
 
     FalseLiteral() { kind = K; }
-    virtual ~FalseLiteral() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -483,7 +478,6 @@ public:
 
     NumericLiteral(double v):
         value(v) { kind = K; }
-    virtual ~NumericLiteral() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -506,8 +500,6 @@ public:
     StringLiteral(NameId *v):
         value (v) { kind = K; }
 
-    virtual ~StringLiteral() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -529,8 +521,6 @@ public:
     RegExpLiteral(NameId *p, int f):
         pattern (p), flags (f) { kind = K; }
 
-    virtual ~RegExpLiteral() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -562,8 +552,6 @@ public:
         elements (elts), elision (e)
         { kind = K; }
 
-    virtual ~ArrayLiteral() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -591,8 +579,6 @@ public:
     ObjectLiteral(PropertyNameAndValueList *plist):
         properties (plist) { kind = K; }
 
-    virtual ~ObjectLiteral() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -624,8 +610,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~ElementList() {}
-
     inline ElementList *finish ()
     {
         ElementList *front = next;
@@ -657,8 +641,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~Elision() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline Elision *finish ()
@@ -690,8 +672,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~PropertyNameAndValueList() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline PropertyNameAndValueList *finish ()
@@ -715,7 +695,6 @@ public:
     QMLJS_DECLARE_AST_NODE(PropertyName)
 
     PropertyName() { kind = K; }
-    virtual ~PropertyName() {}
 
 // attributes
     SourceLocation propertyNameToken;
@@ -729,8 +708,6 @@ public:
     IdentifierPropertyName(NameId *n):
         id (n) { kind = K; }
 
-    virtual ~IdentifierPropertyName() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -744,7 +721,6 @@ public:
 
     StringLiteralPropertyName(NameId *n):
         id (n) { kind = K; }
-    virtual ~StringLiteralPropertyName() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -759,7 +735,6 @@ public:
 
     NumericLiteralPropertyName(double n):
         id (n) { kind = K; }
-    virtual ~NumericLiteralPropertyName() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -776,8 +751,6 @@ public:
         base (b), expression (e)
         { kind = K; }
 
-    virtual ~ArrayMemberExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -802,8 +775,6 @@ public:
         base (b), name (n)
         { kind = K; }
 
-    virtual ~FieldMemberExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -828,8 +799,6 @@ public:
         base (b), arguments (a)
         { kind = K; }
 
-    virtual ~NewMemberExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -854,8 +823,6 @@ public:
     NewExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~NewExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -878,8 +845,6 @@ public:
         base (b), arguments (a)
         { kind = K; }
 
-    virtual ~CallExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -912,8 +877,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~ArgumentList() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline ArgumentList *finish ()
@@ -937,8 +900,6 @@ public:
     PostIncrementExpression(ExpressionNode *b):
         base (b) { kind = K; }
 
-    virtual ~PostIncrementExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -960,8 +921,6 @@ public:
     PostDecrementExpression(ExpressionNode *b):
         base (b) { kind = K; }
 
-    virtual ~PostDecrementExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -982,7 +941,6 @@ public:
 
     DeleteExpression(ExpressionNode *e):
         expression (e) { kind = K; }
-    virtual ~DeleteExpression() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -1005,8 +963,6 @@ public:
     VoidExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~VoidExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1028,8 +984,6 @@ public:
     TypeOfExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~TypeOfExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1051,8 +1005,6 @@ public:
     PreIncrementExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~PreIncrementExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1074,8 +1026,6 @@ public:
     PreDecrementExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~PreDecrementExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1097,8 +1047,6 @@ public:
     UnaryPlusExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~UnaryPlusExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1120,8 +1068,6 @@ public:
     UnaryMinusExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~UnaryMinusExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1143,8 +1089,6 @@ public:
     TildeExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~TildeExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1166,8 +1110,6 @@ public:
     NotExpression(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~NotExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1190,8 +1132,6 @@ public:
         left (l), op (o), right (r)
         { kind = K; }
 
-    virtual ~BinaryExpression() {}
-
     virtual BinaryExpression *binaryExpressionCast();
 
     virtual void accept0(Visitor *visitor);
@@ -1218,8 +1158,6 @@ public:
         expression (e), ok (t), ko (f)
         { kind = K; }
 
-    virtual ~ConditionalExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1244,8 +1182,6 @@ public:
     Expression(ExpressionNode *l, ExpressionNode *r):
         left (l), right (r) { kind = K; }
 
-    virtual ~Expression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1268,8 +1204,6 @@ public:
     Block(StatementList *slist):
         statements (slist) { kind = K; }
 
-    virtual ~Block() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1301,8 +1235,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~StatementList() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline StatementList *finish ()
@@ -1326,8 +1258,6 @@ public:
         declarations (vlist)
         { kind = K; }
 
-    virtual ~VariableStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1351,8 +1281,6 @@ public:
         name (n), expression (e), readOnly(false)
         { kind = K; }
 
-    virtual ~VariableDeclaration() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -1379,8 +1307,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~VariableDeclarationList() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline VariableDeclarationList *finish (bool readOnly)
@@ -1407,7 +1333,6 @@ public:
     QMLJS_DECLARE_AST_NODE(EmptyStatement)
 
     EmptyStatement() { kind = K; }
-    virtual ~EmptyStatement() {}
 
     virtual void accept0(Visitor *visitor);
 
@@ -1429,8 +1354,6 @@ public:
     ExpressionStatement(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~ExpressionStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1453,8 +1376,6 @@ public:
         expression (e), ok (t), ko (f)
         { kind = K; }
 
-    virtual ~IfStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1487,8 +1408,6 @@ public:
         statement (stmt), expression (e)
         { kind = K; }
 
-    virtual ~DoWhileStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1516,8 +1435,6 @@ public:
         expression (e), statement (stmt)
         { kind = K; }
 
-    virtual ~WhileStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1543,8 +1460,6 @@ public:
         initialiser (i), condition (c), expression (e), statement (stmt)
         { kind = K; }
 
-    virtual ~ForStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1574,8 +1489,6 @@ public:
         declarations (vlist), condition (c), expression (e), statement (stmt)
         { kind = K; }
 
-    virtual ~LocalForStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1606,8 +1519,6 @@ public:
         initialiser (i), expression (e), statement (stmt)
         { kind = K; }
 
-    virtual ~ForEachStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1635,8 +1546,6 @@ public:
         declaration (v), expression (e), statement (stmt)
         { kind = K; }
 
-    virtual ~LocalForEachStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1664,8 +1573,6 @@ public:
     ContinueStatement(NameId *l = 0):
         label (l) { kind = K; }
 
-    virtual ~ContinueStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1689,8 +1596,6 @@ public:
     BreakStatement(NameId *l = 0):
         label (l) { kind = K; }
 
-    virtual ~BreakStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1714,8 +1619,6 @@ public:
     ReturnStatement(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~ReturnStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1739,8 +1642,6 @@ public:
         expression (e), statement (stmt)
         { kind = K; }
 
-    virtual ~WithStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1762,12 +1663,10 @@ class QML_PARSER_EXPORT CaseBlock: public Node
 public:
     QMLJS_DECLARE_AST_NODE(CaseBlock)
 
-    explicit CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0):
+    CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0):
         clauses (c), defaultClause (d), moreClauses (r)
         { kind = K; }
 
-    virtual ~CaseBlock() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -1787,8 +1686,6 @@ public:
         expression (e), block (b)
         { kind = K; }
 
-    virtual ~SwitchStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1822,8 +1719,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~CaseClauses() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline CaseClauses *finish ()
@@ -1847,8 +1742,6 @@ public:
         expression (e), statements (slist)
         { kind = K; }
 
-    virtual ~CaseClause() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -1867,8 +1760,6 @@ public:
         statements (slist)
         { kind = K; }
 
-    virtual ~DefaultClause() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -1886,8 +1777,6 @@ public:
         label (l), statement (stmt)
         { kind = K; }
 
-    virtual ~LabelledStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1911,8 +1800,6 @@ public:
     ThrowStatement(ExpressionNode *e):
         expression (e) { kind = K; }
 
-    virtual ~ThrowStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -1936,8 +1823,6 @@ public:
         name (n), statement (stmt)
         { kind = K; }
 
-    virtual ~Catch() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -1958,8 +1843,6 @@ public:
         statement (stmt)
         { kind = K; }
 
-    virtual ~Finally() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -1984,8 +1867,6 @@ public:
         statement (stmt), catchExpression (c), finallyExpression (0)
         { kind = K; }
 
-    virtual ~TryStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -2017,8 +1898,6 @@ public:
         name (n), formals (f), body (b)
         { kind = K; }
 
-    virtual ~FunctionExpression() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -2048,8 +1927,6 @@ public:
         FunctionExpression(n, f, b)
         { kind = K; }
 
-    virtual ~FunctionDeclaration() {}
-
     virtual void accept0(Visitor *visitor);
 };
 
@@ -2070,8 +1947,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~FormalParameterList() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline FormalParameterList *finish ()
@@ -2097,8 +1972,6 @@ public:
         elements (elts)
         { kind = K; }
 
-    virtual ~FunctionBody() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -2114,8 +1987,6 @@ public:
         elements (elts)
         { kind = K; }
 
-    virtual ~Program() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -2139,8 +2010,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~SourceElements() {}
-
     virtual void accept0(Visitor *visitor);
 
     inline SourceElements *finish ()
@@ -2162,8 +2031,6 @@ public:
 
     inline SourceElement()
         { kind = K; }
-
-    virtual ~SourceElement() {}
 };
 
 class QML_PARSER_EXPORT FunctionSourceElement: public SourceElement
@@ -2175,8 +2042,6 @@ public:
         declaration (f)
         { kind = K; }
 
-    virtual ~FunctionSourceElement() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -2192,8 +2057,6 @@ public:
         statement (stmt)
         { kind = K; }
 
-    virtual ~StatementSourceElement() {}
-
     virtual void accept0(Visitor *visitor);
 
 // attributes
@@ -2208,8 +2071,6 @@ public:
     DebuggerStatement()
         { kind = K; }
 
-    virtual ~DebuggerStatement() {}
-
     virtual void accept0(Visitor *visitor);
 
     virtual SourceLocation firstSourceLocation() const
@@ -2256,8 +2117,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~UiQualifiedId() {}
-
     UiQualifiedId *finish()
     {
         UiQualifiedId *head = next;
@@ -2459,8 +2318,6 @@ public:
         previous->next = this;
     }
 
-    virtual ~UiParameterList() {}
-
     virtual void accept0(Visitor *) {}
 
     inline UiParameterList *finish ()
diff --git a/src/libs/qmljs/parser/qmljsastfwd_p.h b/src/libs/qmljs/parser/qmljsastfwd_p.h
index 371739177cc011f2069e96bb76d3b67899a23129..2c42fd9d8963e880194e369424b7c52d5cfab6a2 100644
--- a/src/libs/qmljs/parser/qmljsastfwd_p.h
+++ b/src/libs/qmljs/parser/qmljsastfwd_p.h
@@ -64,7 +64,7 @@ namespace QmlJS { namespace AST {
 class SourceLocation
 {
 public:
-    explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0)
+    SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0)
         : offset(offset), length(length),
           startLine(line), startColumn(column)
     { }
diff --git a/src/libs/qmljs/parser/qmljsgrammar.cpp b/src/libs/qmljs/parser/qmljsgrammar.cpp
index d50454858b81b147547dd23d29018bb6afb3ff57..a0d026b97e61bd650c344f23926715305f1a6c31 100644
--- a/src/libs/qmljs/parser/qmljsgrammar.cpp
+++ b/src/libs/qmljs/parser/qmljsgrammar.cpp
@@ -346,9 +346,9 @@ const short QmlJSGrammar::action_index [] = {
 
 const short QmlJSGrammar::action_info [] = {
   399, 352, 345, -101, 343, 457, 440, 403, 257, -112, 
-  -125, -131, -123, -98, -120, 348, -128, 389, 453, 391, 
+  -125, -131, -123, 346, -120, 348, -128, 389, 453, 391, 
   416, 401, 408, 563, -101, -123, 416, -120, 539, -131, 
-  -98, -112, -125, 348, 257, 99, 71, 645, 621, 101, 
+  346, -112, -125, 348, 257, 99, 71, 645, 621, 101, 
   -128, 440, 141, 621, 164, 431, 539, 430, 453, 573, 
   457, 444, 440, 424, 71, 424, 101, 446, 559, 420, 
   424, 448, 539, 440, 570, 539, 466, 527, 312, 346, 
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
index 0677dd12538600c4c0de30cbcb1b2eecda8b7849..acbc0c214f95970722dc04750a0cb262b5dd070f 100644
--- a/src/libs/qmljs/parser/qmljslexer.cpp
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
@@ -57,7 +57,7 @@
 #include <string.h>
 
 QT_BEGIN_NAMESPACE
-extern double qstrtod(const char *s00, char const **se, bool *ok);
+Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
 QT_END_NAMESPACE
 
 QT_QML_BEGIN_NAMESPACE
@@ -103,7 +103,7 @@ Lexer::Lexer(Engine *eng, bool tokenizeComments)
       prohibitAutomaticSemicolon(false),
       tokenizeComments(tokenizeComments)
 {
-    driver->setLexer(this);
+    if (driver) driver->setLexer(this);
     // allocate space for read buffers
     buffer8 = new char[size8];
     buffer16 = new QChar[size16];
@@ -120,7 +120,7 @@ Lexer::~Lexer()
 
 void Lexer::setCode(const QString &c, int lineno)
 {
-    errmsg = QString();
+    errmsg.clear();
     yylineno = lineno;
     yycolumn = 1;
     restrKeyword = false;
@@ -484,6 +484,8 @@ int Lexer::lex()
         stackToken = -1;
     }
 
+    bool identifierWithEscapedUnicode = false;
+
     while (!done) {
         switch (state) {
         case Start:
@@ -508,22 +510,44 @@ int Lexer::lex()
                     setDone(Eof);
                 }
             } else if (isLineTerminator()) {
-                shiftWindowsLineBreak();
-                yylineno++;
-                yycolumn = 0;
-                bol = true;
-                terminator = true;
-                syncProhibitAutomaticSemicolon();
                 if (restrKeyword) {
+                    // automatic semicolon insertion
+                    recordStartPos();
                     token = QmlJSGrammar::T_SEMICOLON;
                     setDone(Other);
+                } else {
+                    shiftWindowsLineBreak();
+                    yylineno++;
+                    yycolumn = 0;
+                    bol = true;
+                    terminator = true;
+                    syncProhibitAutomaticSemicolon();
                 }
             } else if (current == '"' || current == '\'') {
                 recordStartPos();
                 state = InString;
                 multiLineString = false;
                 stringType = current;
+            } else if (current == '\\' && next1 == 'u') {
+                identifierWithEscapedUnicode = true;
+                recordStartPos();
+
+                shift(2); // skip the unicode escape prefix `\u'
+
+                if (isHexDigit(current) && isHexDigit(next1) &&
+                     isHexDigit(next2) && isHexDigit(next3)) {
+                    record16(convertUnicode(current, next1, next2, next3));
+                    shift(3);
+                    state = InIdentifier;
+                } else {
+                    setDone(Bad);
+                    err = IllegalUnicodeEscapeSequence;
+                    errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
+                    break;
+                }
+
             } else if (isIdentLetter(current)) {
+                identifierWithEscapedUnicode = false;
                 recordStartPos();
                 record16(current);
                 state = InIdentifier;
@@ -656,9 +680,9 @@ int Lexer::lex()
                     setDone(Other);
                 } else
                     state = Start;
-                driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+                if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
             } else if (current == 0) {
-                driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+                if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
                 setDone(Eof);
             }
 
@@ -668,14 +692,14 @@ int Lexer::lex()
                 setDone(Bad);
                 err = UnclosedComment;
                 errmsg = QCoreApplication::translate("QmlParser", "Unclosed comment at end of file");
-                driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+                if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
             } else if (isLineTerminator()) {
                 shiftWindowsLineBreak();
                 yylineno++;
             } else if (current == '*' && next1 == '/') {
                 state = Start;
                 shift(1);
-                driver->addComment(startpos, tokenLength(), startlineno, startcolumn);
+                if (driver) driver->addComment(startpos+2, tokenLength()-3, startlineno, startcolumn+2);
             }
 
             break;
@@ -683,6 +707,21 @@ int Lexer::lex()
             if (isIdentLetter(current) || isDecimalDigit(current)) {
                 record16(current);
                 break;
+            } else if (current == '\\' && next1 == 'u') {
+                identifierWithEscapedUnicode = true;
+                shift(2); // skip the unicode escape prefix `\u'
+
+                if (isHexDigit(current) && isHexDigit(next1) &&
+                     isHexDigit(next2) && isHexDigit(next3)) {
+                    record16(convertUnicode(current, next1, next2, next3));
+                    shift(3);
+                    break;
+                } else {
+                    setDone(Bad);
+                    err = IllegalUnicodeEscapeSequence;
+                    errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
+                    break;
+                }
             }
             setDone(Identifier);
             break;
@@ -825,7 +864,11 @@ int Lexer::lex()
             delimited = true;
         return token;
     case Identifier:
-        if ((token = findReservedWord(buffer16, pos16)) < 0) {
+        token = -1;
+        if (! identifierWithEscapedUnicode)
+            token = findReservedWord(buffer16, pos16);
+
+        if (token < 0) {
             /* TODO: close leak on parse error. same holds true for String */
             if (driver)
                 qsyylval.ustr = driver->intern(buffer16, pos16);
@@ -1104,47 +1147,97 @@ void Lexer::recordStartPos()
 bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
 {
     pos16 = 0;
-    bool lastWasEscape = false;
+    pattern = 0;
 
     if (prefix == EqualPrefix)
         record16(QLatin1Char('='));
 
-    while (1) {
-        if (isLineTerminator() || current == 0) {
+    while (true) {
+        switch (current) {
+
+        case 0: // eof
+        case '\n': case '\r': // line terminator
             errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression literal");
             return false;
-        }
-        else if (current != '/' || lastWasEscape == true)
-            {
-                record16(current);
-                lastWasEscape = !lastWasEscape && (current == '\\');
-            }
-        else {
-            if (driver)
+
+        case '/':
+            shift(1);
+
+            if (driver) // create the pattern
                 pattern = driver->intern(buffer16, pos16);
-            else
-                pattern = 0;
+
+            // scan the flags
             pos16 = 0;
+            flags = 0;
+            while (isIdentLetter(current)) {
+                int flag = Ecma::RegExp::flagFromChar(current);
+                if (flag == 0) {
+                    errmsg = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'")
+                             .arg(QChar(current));
+                    return false;
+                }
+                flags |= flag;
+                record16(current);
+                shift(1);
+            }
+            return true;
+
+        case '\\':
+            // regular expression backslash sequence
+            record16(current);
+            shift(1);
+
+            if (! current || isLineTerminator()) {
+                errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
+                return false;
+            }
+
+            record16(current);
             shift(1);
             break;
-        }
-        shift(1);
-    }
 
-    flags = 0;
-    while (isIdentLetter(current)) {
-        int flag = Ecma::RegExp::flagFromChar(current);
-        if (flag == 0) {
-            errmsg = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'")
-                     .arg(QChar(current));
-            return false;
-        }
-        flags |= flag;
-        record16(current);
-        shift(1);
-    }
+        case '[':
+            // regular expression class
+            record16(current);
+            shift(1);
+
+            while (current && ! isLineTerminator()) {
+                if (current == ']')
+                    break;
+                else if (current == '\\') {
+                    // regular expression backslash sequence
+                    record16(current);
+                    shift(1);
+
+                    if (! current || isLineTerminator()) {
+                        errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
+                        return false;
+                    }
+
+                    record16(current);
+                    shift(1);
+                } else {
+                    record16(current);
+                    shift(1);
+                }
+            }
+
+            if (current != ']') {
+                errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression class");
+                return false;
+            }
+
+            record16(current);
+            shift(1); // skip ]
+            break;
+
+        default:
+            record16(current);
+            shift(1);
+        } // switch
+    } // while
 
-    return true;
+    return false;
 }
 
 void Lexer::syncProhibitAutomaticSemicolon()
diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h
index cf731c7bdb6dfe6ba614c9f05391e7fc7f6a8bd3..8f95a904f44561b259e844b1df90c51606ba53fc 100644
--- a/src/libs/qmljs/parser/qmljslexer_p.h
+++ b/src/libs/qmljs/parser/qmljslexer_p.h
@@ -67,7 +67,7 @@ class NameId;
 class QML_PARSER_EXPORT Lexer
 {
 public:
-    explicit Lexer(Engine *eng, bool tokenizeComments = false);
+    Lexer(Engine *eng, bool tokenizeComments = false);
     ~Lexer();
 
     void setCode(const QString &c, int lineno);