summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
Diffstat (limited to 'qmake')
-rw-r--r--qmake/library/proitems.h3
-rw-r--r--qmake/library/qmakeevaluator.cpp18
-rw-r--r--qmake/library/qmakeparser.cpp26
3 files changed, 46 insertions, 1 deletions
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 05d9e8da28..c81e205699 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -329,6 +329,9 @@ enum ProToken {
// - function name: hash (2), length (1), chars (length)
// - body length (2)
// - body + TokTerminator (body length)
+ TokBypassNesting, // escape from function local variable scopes:
+ // - block length (2)
+ // - block + TokTerminator (block length)
TokMask = 0xff,
TokQuoted = 0x100, // The expression is quoted => join expanded stringlist
TokNewStr = 0x200 // Next stringlist element
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index cc57aa7f2b..4ca87e8bc7 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -594,6 +594,24 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
tokPtr += blockLen;
okey = true, or_op = false; // force next evaluation
break;
+ case TokBypassNesting:
+ blockLen = getBlockLen(tokPtr);
+ if ((m_cumulative || okey != or_op) && blockLen) {
+ ProValueMapStack savedValuemapStack = m_valuemapStack;
+ m_valuemapStack.clear();
+ m_valuemapStack.append(savedValuemapStack.takeFirst());
+ traceMsg("visiting nesting-bypassing block");
+ ret = visitProBlock(tokPtr);
+ traceMsg("visited nesting-bypassing block");
+ savedValuemapStack.prepend(m_valuemapStack.first());
+ m_valuemapStack = savedValuemapStack;
+ } else {
+ traceMsg("skipped nesting-bypassing block");
+ ret = ReturnTrue;
+ }
+ tokPtr += blockLen;
+ okey = true, or_op = false; // force next evaluation
+ break;
case TokTestDef:
case TokReplaceDef:
if (m_cumulative || okey != or_op) {
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 56b217dfbb..78350c76c4 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -118,6 +118,7 @@ static struct {
QString strfor;
QString strdefineTest;
QString strdefineReplace;
+ QString strbypassNesting;
QString stroption;
QString strreturn;
QString strnext;
@@ -141,6 +142,7 @@ void QMakeParser::initialize()
statics.strfor = QLatin1String("for");
statics.strdefineTest = QLatin1String("defineTest");
statics.strdefineReplace = QLatin1String("defineReplace");
+ statics.strbypassNesting = QLatin1String("bypassNesting");
statics.stroption = QLatin1String("option");
statics.strreturn = QLatin1String("return");
statics.strnext = QLatin1String("next");
@@ -1157,6 +1159,25 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
}
parseError(fL1S("%1(function) requires one literal argument.").arg(*defName));
return;
+ } else if (m_tmp == statics.strbypassNesting) {
+ if (*uce != TokFuncTerminator) {
+ bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp));
+ return;
+ }
+ if (!(m_blockstack.top().nest & NestFunction)) {
+ bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp));
+ return;
+ }
+ if (m_invert) {
+ bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
+ return;
+ }
+ flushScopes(tokPtr);
+ putLineMarker(tokPtr);
+ putOperator(tokPtr);
+ putTok(tokPtr, TokBypassNesting);
+ enterScope(tokPtr, true, StCtrl);
+ return;
} else if (m_tmp == statics.strreturn) {
if (m_blockstack.top().nest & NestFunction) {
if (argc > 1) {
@@ -1425,7 +1446,7 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS
"TokReturn", "TokBreak", "TokNext",
"TokNot", "TokAnd", "TokOr",
"TokBranch", "TokForLoop",
- "TokTestDef", "TokReplaceDef"
+ "TokTestDef", "TokReplaceDef", "TokBypassNesting"
};
while (offset != limit) {
@@ -1509,6 +1530,9 @@ static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outS
if (ok)
ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
break;
+ case TokBypassNesting:
+ ok = getSubBlock(tokens, limit, offset, outStr, indent, "block");
+ break;
default:
Q_ASSERT(!"unhandled token");
}