diff --git a/Test/baseResults/tokenPaste.vert.out b/Test/baseResults/tokenPaste.vert.out
index b0f7d10c96cf244103451bb2bb747d15795d533d..9a06c34da9a374f85f306a3bf3dd4615358c14ee 100755
--- a/Test/baseResults/tokenPaste.vert.out
+++ b/Test/baseResults/tokenPaste.vert.out
@@ -63,6 +63,8 @@ ERROR: node is still EOpNull!
 0:?       4 (const int)
 0:?     'cop' (global int)
 0:?     'dop' (global bool)
+0:?     'argPaste2' (uniform int)
+0:?     'argPaste20suff' (uniform int)
 0:?     'gl_VertexID' (gl_VertexId int VertexId)
 0:?     'gl_InstanceID' (gl_InstanceId int InstanceId)
 
@@ -107,6 +109,8 @@ ERROR: node is still EOpNull!
 0:?       4 (const int)
 0:?     'cop' (global int)
 0:?     'dop' (global bool)
+0:?     'argPaste2' (uniform int)
+0:?     'argPaste20suff' (uniform int)
 0:?     'gl_VertexID' (gl_VertexId int VertexId)
 0:?     'gl_InstanceID' (gl_InstanceId int InstanceId)
 
diff --git a/Test/tokenPaste.vert b/Test/tokenPaste.vert
index c30892f091e9da3307124b2a60e949c12d17f6d0..369b7b887669565b67666e8bb44b5c13081cdd2c 100644
--- a/Test/tokenPaste.vert
+++ b/Test/tokenPaste.vert
@@ -68,3 +68,12 @@ void foo()
     // recovery from bad op
     bool f = e MAKE_OP(>,!) 5;
 }
+
+// arguments: should make 'uniform int argPaste2;'
+#define M_NEST(q) int q
+#define M_OUTER(p) M_NEST(p##2)
+uniform M_OUTER(argPaste);
+// should make 'uniform int argPaste20suff;'
+#define M_NEST2(q) int q ## suff
+#define M_OUTER2(p) M_NEST2(p ## 20)
+uniform M_OUTER2(argPaste);
diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index fc96a2229f282728e3a342a8cc7036fafccb0f19..a45d07fb9b824d7f174b7e73742a02322aa99eae 100644
--- a/glslang/Include/revision.h
+++ b/glslang/Include/revision.h
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "Overload400-PrecQual.1819"
-#define GLSLANG_DATE "08-Feb-2017"
+#define GLSLANG_REVISION "Overload400-PrecQual.1820"
+#define GLSLANG_DATE "10-Feb-2017"
diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp
index abce3b5648d69a1f0996c39aaf35e67bf5dba633..6dd02ca646d2e9493096163ea10c9b657f5d7620 100644
--- a/glslang/MachineIndependent/preprocessor/Pp.cpp
+++ b/glslang/MachineIndependent/preprocessor/Pp.cpp
@@ -979,25 +979,13 @@ int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit)
 // Returns nullptr if no expanded argument is created.
 TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
 {
-    // pre-check, to see if anything in the argument needs to be expanded,
-    // to see if we can kick out early
-    int token;
-    RewindTokenStream(arg);
-    do {
-        token = ReadToken(arg, ppToken);
-        if (token == PpAtomIdentifier && lookupMacroDef(atomStrings.getAtom(ppToken->name)) != nullptr)
-            break;
-    } while (token != EndOfInput);
-
-    // if nothing needs to be expanded, kick out early
-    if (token == EndOfInput)
-        return nullptr;
-
     // expand the argument
     TokenStream* expandedArg = new TokenStream;
     pushInput(new tMarkerInput(this));
     pushTokenStreamInput(arg);
+    int token;
     while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
+        token = tokenPaste(token, *ppToken);
         if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
             continue;
         RecordToken(*expandedArg, token, ppToken);
@@ -1263,7 +1251,7 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
         }
 
         // We need both expanded and non-expanded forms of the argument, for whether or
-        // not token pasting is in play.
+        // not token pasting will be applied later when the argument is consumed next to ##.
         for (size_t i = 0; i < in->mac->args.size(); i++)
             in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
     }
diff --git a/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/glslang/MachineIndependent/preprocessor/PpTokens.cpp
index f0441b7f8d2323abd562d008ad97edaaf96e82bb..a8fc9acd11fe927fda527f88183d7cc1a411339c 100644
--- a/glslang/MachineIndependent/preprocessor/PpTokens.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpTokens.cpp
@@ -275,19 +275,37 @@ int TPpContext::tTokenInput::scan(TPpToken* ppToken)
     return pp->ReadToken(*tokens, ppToken);
 }
 
-// We are pasting if the entire macro is preceding a pasting operator
-// (lastTokenPastes) and we are also on the last token.
+// We are pasting if
+//   1. we are preceding a pasting operator within this stream
+// or
+//   2. the entire macro is preceding a pasting operator (lastTokenPastes)
+//      and we are also on the last token
 bool TPpContext::tTokenInput::peekPasting()
 {
+    // 1. preceding ##?
+
+    size_t savePos = tokens->current;
+    int byte;
+    // skip white space
+    do {
+        byte = pp->lReadByte(*tokens);
+    } while (byte == ' ');
+    bool pasting = (byte == ((PpAtomPaste & 0x7f) + 0x80));
+    tokens->current = savePos;
+    if (pasting)
+        return true;
+
+    // 2. last token and we've been told after this there will be a ##
+
     if (! lastTokenPastes)
         return false;
-    // Getting here means the last token will be pasted.
+    // Getting here means the last token will be pasted, after this
 
     // Are we at the last non-whitespace token?
-    size_t savePos = tokens->current;
+    savePos = tokens->current;
     bool moreTokens = false;
     do {
-        int byte = pp->lReadByte(*tokens);
+        byte = pp->lReadByte(*tokens);
         if (byte == EndOfInput)
             break;
         if (byte != ' ') {