#version 450 // side test verifies multiple rounds of argument expansion #define bear SecondExpansion #define mmmB bear #define mmmA(a) a int mmmA(mmmB); // mmmB -> bear, and then in mmmA(), bear -> SecondExpansion // pasting skips the first round of expansion #define mmcatmmdog PostPasteExpansion #define mmcat cat #define mmdog dog #define mmp(a,b) a## b int mmp(mmcat, mmdog); // mmcat/mmdog not expanded, mmcatmmdog -> PostPasteExpansion // multi-token pre #define mmtokpastepre(a) a##27 mmtokpastepre(float foo); // should declare "float foo27;" // multi-token post #define mmtokpastepost(a) uni ##a mmtokpastepost(form float foo155); // should declare "uniform float foo155;" // non-first argument #define foo ShouldntExpandToThis #define semi ; #define bothpaste(a,b) a##b float bothpaste(foo, 719); // should declare "float foo719;" #define secpaste(a,b) a bar ## b secpaste(uniform float, foo semi) // should declare "uniform float barfoo;" // no args #define noArg fl##oat noArg argless; // bad location #define bad1 ## float bad1 dc1; #define bad2 float ## bad2 dc2; // multiple ## #define multiPaste(a, b, c) a##or##b flo##at foo##c multiPaste(unif, m, 875); // too long #define simplePaste(a,b) a##b // 1020 + 5 characters float simplePaste(ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345, 12345); // non-identifiers int a = simplePaste(11,12); // should work in #if as well #define seahorse 1 #define sealion 0 #define marine_animal(suffix) (sea ## suffix) #if marine_animal(horse) // should pass uniform float seahorse_var; #endif #if !marine_animal(lion) // should pass uniform float sealion_var; #endif // operators #define MAKE_OP(L, R) L ## R const int aop = 10; const int bop = 4; int cop = aop MAKE_OP(<, <) bop; bool dop = aop MAKE_OP(!,=) bop; #define MAKE_OP3(L, M, R) L ## M ## R void foo() { int e = 16; e MAKE_OP3(>,>,=) 2; // 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); #define rec(x)## rec(rec()) #define bax(bay) #define baz bax(/##) baz