diff options
author | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2012-09-11 19:30:29 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-09-13 03:42:44 +0200 |
commit | 8400896cfe3fbef7666329a2920bd0dbdd5890af (patch) | |
tree | 4aeef74d80fcf6d7443c3790dcacf43a016c00e9 /qmake/library/qmakeparser.cpp | |
parent | ae3f95a951334dee001e37c305e4d7bf91c0d1b3 (diff) |
don't pretend that break()/next()/return() are functions
it's a pretty braindead thing to implement control flow statements as
(built-in) functions.
as a "side effect", this fixes return() value handling for lists.
(cherry picked from qtcreator/f53ed6c4b3feca59a94d4f0de8b1a7411122e30e)
(cherry picked from qtcreator/f529e22ec38fb9a656d74394e484d2453cf42c69)
Change-Id: I59c8efa0e4d65329327115f7f8ed20719e7f7546
Reviewed-by: Qt Doc Bot <qt_docbot@qt-project.org>
Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Diffstat (limited to 'qmake/library/qmakeparser.cpp')
-rw-r--r-- | qmake/library/qmakeparser.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 660f93517d..04558b8e9b 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -108,6 +108,9 @@ static struct { QString strdefineTest; QString strdefineReplace; QString stroption; + QString strreturn; + QString strnext; + QString strbreak; QString strhost_build; QString strLINE; QString strFILE; @@ -128,6 +131,9 @@ void QMakeParser::initialize() statics.strdefineTest = QLatin1String("defineTest"); statics.strdefineReplace = QLatin1String("defineReplace"); statics.stroption = QLatin1String("option"); + statics.strreturn = QLatin1String("return"); + statics.strnext = QLatin1String("next"); + statics.strbreak = QLatin1String("break"); statics.strhost_build = QLatin1String("host_build"); statics.strLINE = QLatin1String("_LINE_"); statics.strFILE = QLatin1String("_FILE_"); @@ -884,9 +890,11 @@ void QMakeParser::putLineMarker(ushort *&tokPtr) void QMakeParser::enterScope(ushort *&tokPtr, bool special, ScopeState state) { + uchar nest = m_blockstack.top().nest; m_blockstack.resize(m_blockstack.size() + 1); m_blockstack.top().special = special; m_blockstack.top().start = tokPtr; + m_blockstack.top().nest = nest; tokPtr += 2; m_state = state; m_canElse = false; @@ -1026,6 +1034,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg m_tmp.setRawData((QChar *)uc + 4, nlen); const QString *defName; ushort defType; + uchar nest; if (m_tmp == statics.strfor) { if (m_invert || m_operator == OrOperator) { // '|' could actually work reasonably, but qmake does nonsense here. @@ -1048,6 +1057,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg didFor: putTok(tokPtr, TokValueTerminator); enterScope(tokPtr, true, StCtrl); + m_blockstack.top().nest |= NestLoop; return; } else if (*uc == TokArgSeparator && argc == 2) { // for(var, something) @@ -1094,11 +1104,48 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg putTok(tokPtr, defType); putHashStr(tokPtr, uce + 2, nlen); enterScope(tokPtr, true, StCtrl); + m_blockstack.top().nest = NestFunction; return; } } parseError(fL1S("%1(function) requires one literal argument.").arg(*defName)); return; + } else if (m_tmp == statics.strreturn) { + if (argc > 1) { + parseError(fL1S("return() requires zero or one argument.")); + bogusTest(tokPtr); + return; + } + defType = TokReturn; + nest = NestFunction; + goto ctrlstm2; + } else if (m_tmp == statics.strnext) { + defType = TokNext; + goto ctrlstm; + } else if (m_tmp == statics.strbreak) { + defType = TokBreak; + ctrlstm: + if (*uce != TokFuncTerminator) { + parseError(fL1S("%1() requires zero arguments.").arg(m_tmp)); + bogusTest(tokPtr); + return; + } + nest = NestLoop; + ctrlstm2: + if (m_invert) { + parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp)); + bogusTest(tokPtr); + return; + } + if (!(m_blockstack.top().nest & nest)) { + parseError(fL1S("Unexpected %1().").arg(m_tmp)); + bogusTest(tokPtr); + return; + } + finalizeTest(tokPtr); + putBlock(tokPtr, uce, ptr - uce - 1); // Only for TokReturn + putTok(tokPtr, defType); + return; } else if (m_tmp == statics.stroption) { if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1 || m_invert || m_operator != NoOperator) { |