diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index f8b1ebf6b05a5d7819c22661cac82b5e68a7e02a..a6a5dd3eb12e41ca822a5b61f0e295861945328b 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -945,6 +945,7 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro
             m_qmakeGlobals->qmake_abslocation = QDir::cleanPath(qtVersion->qmakeCommand().toString());
             m_qmakeGlobals->setProperties(qtVersion->versionInfo());
         }
+        m_qmakeGlobals->setDirectories(m_rootProjectNode->sourceDir(), m_rootProjectNode->buildDir());
         m_qmakeGlobals->sysroot = systemRoot;
 
         Utils::Environment::const_iterator eit = env.constBegin(), eend = env.constEnd();
diff --git a/src/shared/proparser/qmakebuiltins.cpp b/src/shared/proparser/qmakebuiltins.cpp
index bf6023b9ff93a4dbc85e61107849211213eabd0a..630d1fb0805fceff42975280cd7325a49258bb9e 100644
--- a/src/shared/proparser/qmakebuiltins.cpp
+++ b/src/shared/proparser/qmakebuiltins.cpp
@@ -76,7 +76,8 @@ enum ExpandFunc {
     E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
     E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
     E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
-    E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS
+    E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
+    E_SHADOWED
 };
 
 enum TestFunc {
@@ -123,6 +124,7 @@ void QMakeEvaluator::initFunctionStatics()
         { "sort_depends", E_SORT_DEPENDS },
         { "resolve_depends", E_RESOLVE_DEPENDS },
         { "enumerate_vars", E_ENUMERATE_VARS },
+        { "shadowed", E_SHADOWED },
     };
     for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
         statics.expands.insert(ProString(expandInits[i].name), expandInits[i].func);
@@ -819,6 +821,21 @@ ProStringList QMakeEvaluator::evaluateExpandFunction(
         foreach (const ProString &key, keys)
             ret << key;
         break; }
+    case E_SHADOWED:
+        if (args.count() != 1) {
+            evalError(fL1S("shadowed(path) requires one argument."));
+        } else {
+            QString val = resolvePath(args.at(0).toQString(m_tmp1));
+            if (m_option->source_root.isEmpty()) {
+                ret += ProString(val, NoHash);
+            } else if (val.startsWith(m_option->source_root)
+                       && (val.length() == m_option->source_root.length()
+                           || val.at(m_option->source_root.length()) == QLatin1Char('/'))) {
+                ret += ProString(m_option->build_root + val.mid(m_option->source_root.length()),
+                                 NoHash).setSource(args.at(0));
+            }
+        }
+        break;
     case E_INVALID:
         evalError(fL1S("'%1' is not a recognized replace function.")
                   .arg(func.toQString(m_tmp1)));
diff --git a/src/shared/proparser/qmakeglobals.cpp b/src/shared/proparser/qmakeglobals.cpp
index b06e34f457add56dcc7f60e0714c8a8ff04d9446..0c112870cde38e3cb112f1e7d878cef659f1dffc 100644
--- a/src/shared/proparser/qmakeglobals.cpp
+++ b/src/shared/proparser/qmakeglobals.cpp
@@ -148,6 +148,26 @@ void QMakeGlobals::setCommandLineArguments(const QStringList &args)
     postcmds = _postcmds.join(fL1S("\n"));
 }
 
+void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir)
+{
+    if (input_dir != output_dir && !output_dir.isEmpty()) {
+        QString srcpath = input_dir;
+        if (!srcpath.endsWith(QLatin1Char('/')))
+            srcpath += QLatin1Char('/');
+        QString dstpath = output_dir;
+        if (!dstpath.endsWith(QLatin1Char('/')))
+            dstpath += QLatin1Char('/');
+        int srcLen = srcpath.length();
+        int dstLen = dstpath.length();
+        int lastSl = -1;
+        while (++lastSl, srcpath.at(--srcLen) == dstpath.at(--dstLen))
+            if (srcpath.at(srcLen) == QLatin1Char('/'))
+                lastSl = 0;
+        source_root = srcpath.left(srcLen + lastSl);
+        build_root = dstpath.left(dstLen + lastSl);
+    }
+}
+
 QString QMakeGlobals::getEnv(const QString &var) const
 {
 #ifndef QT_BOOTSTRAPPED
diff --git a/src/shared/proparser/qmakeglobals.h b/src/shared/proparser/qmakeglobals.h
index 8ca220aac4e4c3f5d32d48982ca1d2581ab7b608..38044f21a6a165493acff86a08d4ea1865b59adf 100644
--- a/src/shared/proparser/qmakeglobals.h
+++ b/src/shared/proparser/qmakeglobals.h
@@ -99,6 +99,7 @@ public:
     // -nocache, -cache, -spec, QMAKESPEC
     // -set persistent value
     void setCommandLineArguments(const QStringList &args);
+    void setDirectories(const QString &input_dir, const QString &output_dir);
 #ifdef PROEVALUATOR_INIT_PROPS
     bool initProperties();
 #else
@@ -112,6 +113,8 @@ private:
     QString getEnv(const QString &) const;
     QStringList getPathListEnv(const QString &var) const;
 
+    QString source_root, build_root;
+
     QString precmds, postcmds;
     QHash<ProString, ProString> properties;
 
diff --git a/tests/manual/proparser/main.cpp b/tests/manual/proparser/main.cpp
index b686672104cda424a805a1b56c032e3989cea7c6..110e1f0f98aa7673a7e5f2e0c4b4f0f0c6cd678d 100644
--- a/tests/manual/proparser/main.cpp
+++ b/tests/manual/proparser/main.cpp
@@ -168,6 +168,7 @@ int main(int argc, char **argv)
     QString file = infi.absoluteFilePath();
     QString in_pwd = infi.absolutePath();
     QString out_pwd = (args.count() > 2) ? QFileInfo(args[2]).absoluteFilePath() : in_pwd;
+    option.setDirectories(in_pwd, out_pwd);
 
     return evaluate(file, in_pwd, out_pwd, cumulative, &option, &parser, level);
 }