• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include <sstream>
8 
9 #include "PreprocessorTest.h"
10 #include "compiler/preprocessor/Token.h"
11 
12 namespace angle
13 {
14 
15 using testing::_;
16 
17 class DefineTest : public SimplePreprocessorTest
18 {};
19 
TEST_F(DefineTest,NonIdentifier)20 TEST_F(DefineTest, NonIdentifier)
21 {
22     const char *input =
23         "#define 2 foo\n"
24         "2\n";
25     const char *expected =
26         "\n"
27         "2\n";
28 
29     EXPECT_CALL(mDiagnostics,
30                 print(pp::Diagnostics::PP_UNEXPECTED_TOKEN, pp::SourceLocation(0, 1), "2"));
31 
32     preprocess(input, expected);
33 }
34 
TEST_F(DefineTest,RedefinePredefined)35 TEST_F(DefineTest, RedefinePredefined)
36 {
37     const char *input =
38         "#define __LINE__ 10\n"
39         "__LINE__\n"
40         "#define __FILE__ 20\n"
41         "__FILE__\n"
42         "#define __VERSION__ 200\n"
43         "__VERSION__\n"
44         "#define GL_ES 0\n"
45         "GL_ES\n";
46     const char *expected =
47         "\n"
48         "2\n"
49         "\n"
50         "0\n"
51         "\n"
52         "100\n"
53         "\n"
54         "1\n";
55 
56     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
57                                     pp::SourceLocation(0, 1), "__LINE__"));
58     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
59                                     pp::SourceLocation(0, 3), "__FILE__"));
60     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
61                                     pp::SourceLocation(0, 5), "__VERSION__"));
62     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
63                                     pp::SourceLocation(0, 7), "GL_ES"));
64 
65     preprocess(input, expected);
66 }
67 
TEST_F(DefineTest,ReservedUnderScore1)68 TEST_F(DefineTest, ReservedUnderScore1)
69 {
70     const char *input =
71         "#define __foo bar\n"
72         "__foo\n";
73     const char *expected =
74         "\n"
75         "bar\n";
76 
77     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_WARNING_MACRO_NAME_RESERVED,
78                                     pp::SourceLocation(0, 1), "__foo"));
79 
80     preprocess(input, expected);
81 }
82 
TEST_F(DefineTest,ReservedUnderScore2)83 TEST_F(DefineTest, ReservedUnderScore2)
84 {
85     const char *input =
86         "#define foo__bar baz\n"
87         "foo__bar\n";
88     const char *expected =
89         "\n"
90         "baz\n";
91 
92     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_WARNING_MACRO_NAME_RESERVED,
93                                     pp::SourceLocation(0, 1), "foo__bar"));
94 
95     preprocess(input, expected);
96 }
97 
TEST_F(DefineTest,ReservedGL)98 TEST_F(DefineTest, ReservedGL)
99 {
100     const char *input =
101         "#define GL_foo bar\n"
102         "GL_foo\n";
103     const char *expected =
104         "\n"
105         "GL_foo\n";
106 
107     EXPECT_CALL(mDiagnostics,
108                 print(pp::Diagnostics::PP_MACRO_NAME_RESERVED, pp::SourceLocation(0, 1), "GL_foo"));
109 
110     preprocess(input, expected);
111 }
112 
TEST_F(DefineTest,ObjRedefineValid)113 TEST_F(DefineTest, ObjRedefineValid)
114 {
115     const char *input =
116         "#define foo (1-1)\n"
117         "#define foo /* whitespace */ (1-1) /* other */ \n"
118         "foo\n";
119     const char *expected =
120         "\n"
121         "\n"
122         "(1-1)\n";
123     // No error or warning.
124     using testing::_;
125     EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
126 
127     preprocess(input, expected);
128 }
129 
TEST_F(DefineTest,ObjRedefineInvalid)130 TEST_F(DefineTest, ObjRedefineInvalid)
131 {
132     const char *input =
133         "#define foo (0)\n"
134         "#define foo (1-1)\n"
135         "foo\n";
136     const char *expected =
137         "\n"
138         "\n"
139         "(0)\n";
140 
141     EXPECT_CALL(mDiagnostics,
142                 print(pp::Diagnostics::PP_MACRO_REDEFINED, pp::SourceLocation(0, 2), "foo"));
143 
144     preprocess(input, expected);
145 }
146 
TEST_F(DefineTest,FuncRedefineValid)147 TEST_F(DefineTest, FuncRedefineValid)
148 {
149     const char *input =
150         "#define foo(a) ( a )\n"
151         "#define foo( a )( /* whitespace */ a /* other */ )\n"
152         "foo(b)\n";
153     const char *expected =
154         "\n"
155         "\n"
156         "( b )\n";
157     // No error or warning.
158     using testing::_;
159     EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
160 
161     preprocess(input, expected);
162 }
163 
TEST_F(DefineTest,FuncRedefineInvalid)164 TEST_F(DefineTest, FuncRedefineInvalid)
165 {
166     const char *input =
167         "#define foo(b) ( a )\n"
168         "#define foo(b) ( b )\n"
169         "foo(1)\n";
170     const char *expected =
171         "\n"
172         "\n"
173         "( a )\n";
174 
175     EXPECT_CALL(mDiagnostics,
176                 print(pp::Diagnostics::PP_MACRO_REDEFINED, pp::SourceLocation(0, 2), "foo"));
177 
178     preprocess(input, expected);
179 }
180 
TEST_F(DefineTest,ObjBasic)181 TEST_F(DefineTest, ObjBasic)
182 {
183     const char *input =
184         "#define foo 1\n"
185         "foo\n";
186     const char *expected =
187         "\n"
188         "1\n";
189 
190     preprocess(input, expected);
191 }
192 
TEST_F(DefineTest,ObjEmpty)193 TEST_F(DefineTest, ObjEmpty)
194 {
195     const char *input =
196         "#define foo\n"
197         "foo\n";
198     const char *expected =
199         "\n"
200         "\n";
201 
202     preprocess(input, expected);
203 }
204 
TEST_F(DefineTest,ObjChain)205 TEST_F(DefineTest, ObjChain)
206 {
207     const char *input =
208         "#define foo 1\n"
209         "#define bar foo\n"
210         "bar\n";
211     const char *expected =
212         "\n"
213         "\n"
214         "1\n";
215 
216     preprocess(input, expected);
217 }
218 
TEST_F(DefineTest,ObjChainReverse)219 TEST_F(DefineTest, ObjChainReverse)
220 {
221     const char *input =
222         "#define bar foo\n"
223         "#define foo 1\n"
224         "bar\n";
225     const char *expected =
226         "\n"
227         "\n"
228         "1\n";
229 
230     preprocess(input, expected);
231 }
232 
TEST_F(DefineTest,ObjRecursive)233 TEST_F(DefineTest, ObjRecursive)
234 {
235     const char *input =
236         "#define foo bar\n"
237         "#define bar baz\n"
238         "#define baz foo\n"
239         "foo\n"
240         "bar\n"
241         "baz\n";
242     const char *expected =
243         "\n"
244         "\n"
245         "\n"
246         "foo\n"
247         "bar\n"
248         "baz\n";
249 
250     preprocess(input, expected);
251 }
252 
TEST_F(DefineTest,ObjCompositeChain)253 TEST_F(DefineTest, ObjCompositeChain)
254 {
255     const char *input =
256         "#define foo 1\n"
257         "#define bar a foo\n"
258         "bar\n";
259     const char *expected =
260         "\n"
261         "\n"
262         "a 1\n";
263 
264     preprocess(input, expected);
265 }
266 
TEST_F(DefineTest,ObjCompositeChainReverse)267 TEST_F(DefineTest, ObjCompositeChainReverse)
268 {
269     const char *input =
270         "#define bar a foo\n"
271         "#define foo 1\n"
272         "bar\n";
273     const char *expected =
274         "\n"
275         "\n"
276         "a 1\n";
277 
278     preprocess(input, expected);
279 }
280 
TEST_F(DefineTest,ObjCompositeRecursive)281 TEST_F(DefineTest, ObjCompositeRecursive)
282 {
283     const char *input =
284         "#define foo a bar\n"
285         "#define bar b baz\n"
286         "#define baz c foo\n"
287         "foo\n"
288         "bar\n"
289         "baz\n";
290     const char *expected =
291         "\n"
292         "\n"
293         "\n"
294         "a b c foo\n"
295         "b c a bar\n"
296         "c a b baz\n";
297 
298     preprocess(input, expected);
299 }
300 
TEST_F(DefineTest,ObjChainSelfRecursive)301 TEST_F(DefineTest, ObjChainSelfRecursive)
302 {
303     const char *input =
304         "#define foo foo\n"
305         "#define bar foo\n"
306         "bar\n";
307     const char *expected =
308         "\n"
309         "\n"
310         "foo\n";
311 
312     preprocess(input, expected);
313 }
314 
TEST_F(DefineTest,ObjectLikeWithParens)315 TEST_F(DefineTest, ObjectLikeWithParens)
316 {
317     const char *input =
318         "#define foo ()1\n"
319         "foo()\n"
320         "#define bar ()2\n"
321         "bar()\n";
322     const char *expected =
323         "\n"
324         "()1()\n"
325         "\n"
326         "()2()\n";
327 
328     preprocess(input, expected);
329 }
330 
TEST_F(DefineTest,FuncEmpty)331 TEST_F(DefineTest, FuncEmpty)
332 {
333     const char *input =
334         "#define foo()\n"
335         "foo()\n";
336     const char *expected =
337         "\n"
338         "\n";
339 
340     preprocess(input, expected);
341 }
342 
TEST_F(DefineTest,FuncNoArgs)343 TEST_F(DefineTest, FuncNoArgs)
344 {
345     const char *input =
346         "#define foo() bar\n"
347         "foo()\n";
348     const char *expected =
349         "\n"
350         "bar\n";
351 
352     preprocess(input, expected);
353 }
354 
TEST_F(DefineTest,FuncOneArgUnused)355 TEST_F(DefineTest, FuncOneArgUnused)
356 {
357     const char *input =
358         "#define foo(x) 1\n"
359         "foo(bar)\n";
360     const char *expected =
361         "\n"
362         "1\n";
363 
364     preprocess(input, expected);
365 }
366 
TEST_F(DefineTest,FuncTwoArgsUnused)367 TEST_F(DefineTest, FuncTwoArgsUnused)
368 {
369     const char *input =
370         "#define foo(x,y) 1\n"
371         "foo(bar,baz)\n";
372     const char *expected =
373         "\n"
374         "1\n";
375 
376     preprocess(input, expected);
377 }
378 
TEST_F(DefineTest,FuncOneArg)379 TEST_F(DefineTest, FuncOneArg)
380 {
381     const char *input =
382         "#define foo(x) ((x)+1)\n"
383         "foo(bar)\n";
384     const char *expected =
385         "\n"
386         "((bar)+1)\n";
387 
388     preprocess(input, expected);
389 }
390 
TEST_F(DefineTest,FuncTwoArgs)391 TEST_F(DefineTest, FuncTwoArgs)
392 {
393     const char *input =
394         "#define foo(x,y) ((x)*(y))\n"
395         "foo(bar,baz)\n";
396     const char *expected =
397         "\n"
398         "((bar)*(baz))\n";
399 
400     preprocess(input, expected);
401 }
402 
TEST_F(DefineTest,FuncEmptyArgs)403 TEST_F(DefineTest, FuncEmptyArgs)
404 {
405     const char *input =
406         "#define zero() pass\n"
407         "#define one(x) pass\n"
408         "#define two(x,y) pass\n"
409         "zero()\n"
410         "one()\n"
411         "two(,)\n";
412     const char *expected =
413         "\n"
414         "\n"
415         "\n"
416         "pass\n"
417         "pass\n"
418         "pass\n";
419 
420     preprocess(input, expected);
421 }
422 
TEST_F(DefineTest,FuncMacroAsParam)423 TEST_F(DefineTest, FuncMacroAsParam)
424 {
425     const char *input =
426         "#define x 0\n"
427         "#define foo(x) x\n"
428         "foo(1)\n";
429     const char *expected =
430         "\n"
431         "\n"
432         "1\n";
433 
434     preprocess(input, expected);
435 }
436 
TEST_F(DefineTest,FuncOneArgMulti)437 TEST_F(DefineTest, FuncOneArgMulti)
438 {
439     const char *input =
440         "#define foo(x) (x)\n"
441         "foo(this is a multi-word argument)\n";
442     const char *expected =
443         "\n"
444         "(this is a multi-word argument)\n";
445 
446     preprocess(input, expected);
447 }
448 
TEST_F(DefineTest,FuncTwoArgsMulti)449 TEST_F(DefineTest, FuncTwoArgsMulti)
450 {
451     const char *input =
452         "#define foo(x,y) x,two fish,red fish,y\n"
453         "foo(one fish, blue fish)\n";
454     const char *expected =
455         "\n"
456         "one fish,two fish,red fish,blue fish\n";
457 
458     preprocess(input, expected);
459 }
460 
TEST_F(DefineTest,FuncCompose)461 TEST_F(DefineTest, FuncCompose)
462 {
463     const char *input =
464         "#define bar(x) (1+(x))\n"
465         "#define foo(y) (2*(y))\n"
466         "foo(bar(3))\n";
467     const char *expected =
468         "\n"
469         "\n"
470         "(2*((1+(3))))\n";
471 
472     preprocess(input, expected);
473 }
474 
TEST_F(DefineTest,FuncArgWithParens)475 TEST_F(DefineTest, FuncArgWithParens)
476 {
477     const char *input =
478         "#define foo(x) (x)\n"
479         "foo(argument(with parens) FTW)\n";
480     const char *expected =
481         "\n"
482         "(argument(with parens) FTW)\n";
483 
484     preprocess(input, expected);
485 }
486 
TEST_F(DefineTest,FuncMacroAsNonMacro)487 TEST_F(DefineTest, FuncMacroAsNonMacro)
488 {
489     const char *input =
490         "#define foo(bar) bar\n"
491         "foo bar\n";
492     const char *expected =
493         "\n"
494         "foo bar\n";
495 
496     preprocess(input, expected);
497 }
498 
TEST_F(DefineTest,FuncExtraNewlines)499 TEST_F(DefineTest, FuncExtraNewlines)
500 {
501     const char *input =
502         "#define foo(a) (a)\n"
503         "foo\n"
504         "(\n"
505         "1\n"
506         ")\n";
507     const char *expected =
508         "\n"
509         "\n"
510         "\n"
511         "\n"
512         "(1)\n";
513 
514     preprocess(input, expected);
515 }
516 
TEST_F(DefineTest,ChainObjToFunc)517 TEST_F(DefineTest, ChainObjToFunc)
518 {
519     const char *input =
520         "#define foo() pass\n"
521         "#define bar foo()\n"
522         "bar\n";
523     const char *expected =
524         "\n"
525         "\n"
526         "pass\n";
527 
528     preprocess(input, expected);
529 }
530 
TEST_F(DefineTest,ChainObjToNonFunc)531 TEST_F(DefineTest, ChainObjToNonFunc)
532 {
533     const char *input =
534         "#define pass() fail\n"
535         "#define bar pass\n"
536         "bar\n";
537     const char *expected =
538         "\n"
539         "\n"
540         "pass\n";
541 
542     preprocess(input, expected);
543 }
544 
TEST_F(DefineTest,ChainObjToFuncWithArgs)545 TEST_F(DefineTest, ChainObjToFuncWithArgs)
546 {
547     const char *input =
548         "#define foo(fail) fail\n"
549         "#define bar foo(pass)\n"
550         "bar\n";
551     const char *expected =
552         "\n"
553         "\n"
554         "pass\n";
555 
556     preprocess(input, expected);
557 }
558 
TEST_F(DefineTest,ChainObjToFuncCompose)559 TEST_F(DefineTest, ChainObjToFuncCompose)
560 {
561     const char *input =
562         "#define baz(fail) fail\n"
563         "#define bar(fail) fail\n"
564         "#define foo bar(baz(pass))\n"
565         "foo\n";
566     const char *expected =
567         "\n"
568         "\n"
569         "\n"
570         "pass\n";
571 
572     preprocess(input, expected);
573 }
574 
TEST_F(DefineTest,ChainObjToFuncParensInText1)575 TEST_F(DefineTest, ChainObjToFuncParensInText1)
576 {
577     const char *input =
578         "#define fail() pass\n"
579         "#define foo fail\n"
580         "foo()\n";
581     const char *expected =
582         "\n"
583         "\n"
584         "pass\n";
585 
586     preprocess(input, expected);
587 }
588 
TEST_F(DefineTest,ChainObjToFuncParensInText2)589 TEST_F(DefineTest, ChainObjToFuncParensInText2)
590 {
591     const char *input =
592         "#define bar with,embedded,commas\n"
593         "#define func(x) pass\n"
594         "#define foo func\n"
595         "foo(bar)\n";
596     const char *expected =
597         "\n"
598         "\n"
599         "\n"
600         "pass\n";
601 
602     preprocess(input, expected);
603 }
604 
TEST_F(DefineTest,ChainObjToFuncMultiLevel)605 TEST_F(DefineTest, ChainObjToFuncMultiLevel)
606 {
607     const char *input =
608         "#define foo(x) pass\n"
609         "#define bar foo\n"
610         "#define baz bar\n"
611         "#define joe baz\n"
612         "joe (fail)\n";
613     const char *expected =
614         "\n"
615         "\n"
616         "\n"
617         "\n"
618         "pass\n";
619 
620     preprocess(input, expected);
621 }
622 
TEST_F(DefineTest,ObjToFuncRecursive)623 TEST_F(DefineTest, ObjToFuncRecursive)
624 {
625     const char *input =
626         "#define A(a,b) B(a,b)\n"
627         "#define C A(0,C)\n"
628         "C\n";
629     const char *expected =
630         "\n"
631         "\n"
632         "B(0,C)\n";
633 
634     preprocess(input, expected);
635 }
636 
TEST_F(DefineTest,ChainFuncToFuncCompose)637 TEST_F(DefineTest, ChainFuncToFuncCompose)
638 {
639     const char *input =
640         "#define baz(fail) fail\n"
641         "#define bar(fail) fail\n"
642         "#define foo() bar(baz(pass))\n"
643         "foo()\n";
644     const char *expected =
645         "\n"
646         "\n"
647         "\n"
648         "pass\n";
649 
650     preprocess(input, expected);
651 }
652 
TEST_F(DefineTest,FuncSelfRecursive)653 TEST_F(DefineTest, FuncSelfRecursive)
654 {
655     const char *input =
656         "#define foo(a) foo(2*(a))\n"
657         "foo(3)\n";
658     const char *expected =
659         "\n"
660         "foo(2*(3))\n";
661 
662     preprocess(input, expected);
663 }
664 
TEST_F(DefineTest,FuncSelfCompose)665 TEST_F(DefineTest, FuncSelfCompose)
666 {
667     const char *input =
668         "#define foo(a) foo(2*(a))\n"
669         "foo(foo(3))\n";
670     const char *expected =
671         "\n"
672         "foo(2*(foo(2*(3))))\n";
673 
674     preprocess(input, expected);
675 }
676 
TEST_F(DefineTest,FuncSelfComposeNonFunc)677 TEST_F(DefineTest, FuncSelfComposeNonFunc)
678 {
679     const char *input =
680         "#define foo(bar) bar\n"
681         "foo(foo)\n";
682     const char *expected =
683         "\n"
684         "foo\n";
685 
686     preprocess(input, expected);
687 }
688 
TEST_F(DefineTest,FuncSelfComposeNonFuncMultiTokenArg)689 TEST_F(DefineTest, FuncSelfComposeNonFuncMultiTokenArg)
690 {
691     const char *input =
692         "#define foo(bar) bar\n"
693         "foo(1+foo)\n";
694     const char *expected =
695         "\n"
696         "1+foo\n";
697 
698     preprocess(input, expected);
699 }
700 
TEST_F(DefineTest,FinalizeUnexpandedMacro)701 TEST_F(DefineTest, FinalizeUnexpandedMacro)
702 {
703     const char *input =
704         "#define expand(x) expand(x once)\n"
705         "#define foo(x) x\n"
706         "foo(expand(just))\n";
707     const char *expected =
708         "\n"
709         "\n"
710         "expand(just once)\n";
711 
712     preprocess(input, expected);
713 }
714 
TEST_F(DefineTest,FuncArgWithCommas)715 TEST_F(DefineTest, FuncArgWithCommas)
716 {
717     const char *input =
718         "#define foo(x) pass\n"
719         "foo(argument (with,embedded, commas) -- baz)\n";
720     const char *expected =
721         "\n"
722         "pass\n";
723 
724     preprocess(input, expected);
725 }
726 
TEST_F(DefineTest,FuncArgObjMaroWithComma)727 TEST_F(DefineTest, FuncArgObjMaroWithComma)
728 {
729     const char *input =
730         "#define foo(a) (a)\n"
731         "#define bar two,words\n"
732         "foo(bar)\n";
733     const char *expected =
734         "\n"
735         "\n"
736         "(two,words)\n";
737 
738     preprocess(input, expected);
739 }
740 
TEST_F(DefineTest,FuncLeftParenInMacroRightParenInText)741 TEST_F(DefineTest, FuncLeftParenInMacroRightParenInText)
742 {
743     const char *input =
744         "#define bar(a) a*2\n"
745         "#define foo bar(\n"
746         "foo b)\n";
747     const char *expected =
748         "\n"
749         "\n"
750         "b*2\n";
751 
752     preprocess(input, expected);
753 }
754 
TEST_F(DefineTest,RepeatedArg)755 TEST_F(DefineTest, RepeatedArg)
756 {
757     const char *input =
758         "#define double(x) x x\n"
759         "double(1)\n";
760     const char *expected =
761         "\n"
762         "1 1\n";
763 
764     preprocess(input, expected);
765 }
766 
TEST_F(DefineTest,FuncMissingRightParen)767 TEST_F(DefineTest, FuncMissingRightParen)
768 {
769     const char *input =
770         "#define foo(x) (2*(x))\n"
771         "foo(3\n";
772     const char *expected =
773         "\n"
774         "\n";
775 
776     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION,
777                                     pp::SourceLocation(0, 2), "foo"));
778 
779     preprocess(input, expected);
780 }
781 
TEST_F(DefineTest,FuncIncorrectArgCount)782 TEST_F(DefineTest, FuncIncorrectArgCount)
783 {
784     const char *input =
785         "#define foo(x,y) ((x)+(y))\n"
786         "foo()\n"
787         "foo(1)\n"
788         "foo(1,2,3)\n";
789     const char *expected =
790         "\n"
791         "\n"
792         "\n"
793         "\n";
794 
795     EXPECT_CALL(mDiagnostics,
796                 print(pp::Diagnostics::PP_MACRO_TOO_FEW_ARGS, pp::SourceLocation(0, 2), "foo"));
797     EXPECT_CALL(mDiagnostics,
798                 print(pp::Diagnostics::PP_MACRO_TOO_FEW_ARGS, pp::SourceLocation(0, 3), "foo"));
799     EXPECT_CALL(mDiagnostics,
800                 print(pp::Diagnostics::PP_MACRO_TOO_MANY_ARGS, pp::SourceLocation(0, 4), "foo"));
801 
802     preprocess(input, expected);
803 }
804 
TEST_F(DefineTest,Undef)805 TEST_F(DefineTest, Undef)
806 {
807     const char *input =
808         "#define foo 1\n"
809         "foo\n"
810         "#undef foo\n"
811         "foo\n";
812     const char *expected =
813         "\n"
814         "1\n"
815         "\n"
816         "foo\n";
817 
818     preprocess(input, expected);
819 }
820 
TEST_F(DefineTest,UndefPredefined)821 TEST_F(DefineTest, UndefPredefined)
822 {
823     const char *input =
824         "#undef __LINE__\n"
825         "__LINE__\n"
826         "#undef __FILE__\n"
827         "__FILE__\n"
828         "#undef __VERSION__\n"
829         "__VERSION__\n"
830         "#undef GL_ES\n"
831         "GL_ES\n";
832     const char *expected =
833         "\n"
834         "2\n"
835         "\n"
836         "0\n"
837         "\n"
838         "100\n"
839         "\n"
840         "1\n";
841 
842     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
843                                     pp::SourceLocation(0, 1), "__LINE__"));
844     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
845                                     pp::SourceLocation(0, 3), "__FILE__"));
846     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
847                                     pp::SourceLocation(0, 5), "__VERSION__"));
848     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
849                                     pp::SourceLocation(0, 7), "GL_ES"));
850 
851     preprocess(input, expected);
852 }
853 
TEST_F(DefineTest,UndefRedefine)854 TEST_F(DefineTest, UndefRedefine)
855 {
856     const char *input =
857         "#define foo 1\n"
858         "foo\n"
859         "#undef foo\n"
860         "foo\n"
861         "#define foo 2\n"
862         "foo\n";
863     const char *expected =
864         "\n"
865         "1\n"
866         "\n"
867         "foo\n"
868         "\n"
869         "2\n";
870 
871     preprocess(input, expected);
872 }
873 
874 // Example from C99 standard section 6.10.3.5 Scope of macro definitions
TEST_F(DefineTest,C99Example)875 TEST_F(DefineTest, C99Example)
876 {
877     const char *input =
878         "#define x    3          \n"
879         "#define f(a) f(x * (a)) \n"
880         "#undef  x               \n"
881         "#define x    2          \n"
882         "#define g    f          \n"
883         "#define z    z[0]       \n"
884         "#define h    g(~        \n"
885         "#define m(a) a(w)       \n"
886         "#define w    0,1        \n"
887         "#define t(a) a          \n"
888         "#define p()  int        \n"
889         "#define q(x) x          \n"
890         "                        \n"
891         "f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);\n"
892         "g(x+(3,4)-w) | h 5) & m\n"
893         "    (f)^m(m);\n"
894         "p() i[q()] = { q(1), 23, 4, 5, };\n";
895     const char *expected =
896         "\n"
897         "\n"
898         "\n"
899         "\n"
900         "\n"
901         "\n"
902         "\n"
903         "\n"
904         "\n"
905         "\n"
906         "\n"
907         "\n"
908         "\n"
909         "f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);\n"
910         "f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) &\n"
911         " f(2 * (0,1))^m(0,1);\n"
912         "int i[] = { 1, 23, 4, 5, };\n";
913 
914     preprocess(input, expected);
915 }
916 
TEST_F(DefineTest,Predefined_GL_ES)917 TEST_F(DefineTest, Predefined_GL_ES)
918 {
919     const char *input    = "GL_ES\n";
920     const char *expected = "1\n";
921 
922     preprocess(input, expected);
923 }
924 
TEST_F(DefineTest,Predefined_VERSION)925 TEST_F(DefineTest, Predefined_VERSION)
926 {
927     const char *input    = "__VERSION__\n";
928     const char *expected = "100\n";
929 
930     preprocess(input, expected);
931 }
932 
TEST_F(DefineTest,Predefined_LINE1)933 TEST_F(DefineTest, Predefined_LINE1)
934 {
935     const char *str = "\n\n__LINE__";
936 
937     pp::Token token;
938     lexSingleToken(str, &token);
939     EXPECT_EQ(pp::Token::CONST_INT, token.type);
940     EXPECT_EQ("3", token.text);
941 }
942 
TEST_F(DefineTest,Predefined_LINE2)943 TEST_F(DefineTest, Predefined_LINE2)
944 {
945     const char *str =
946         "#line 10\n"
947         "__LINE__\n";
948 
949     pp::Token token;
950     lexSingleToken(str, &token);
951     EXPECT_EQ(pp::Token::CONST_INT, token.type);
952     EXPECT_EQ("10", token.text);
953 }
954 
TEST_F(DefineTest,Predefined_FILE1)955 TEST_F(DefineTest, Predefined_FILE1)
956 {
957     const char *const str[] = {"", "", "__FILE__"};
958 
959     pp::Token token;
960     lexSingleToken(3, str, &token);
961     EXPECT_EQ(pp::Token::CONST_INT, token.type);
962     EXPECT_EQ("2", token.text);
963 }
964 
TEST_F(DefineTest,Predefined_FILE2)965 TEST_F(DefineTest, Predefined_FILE2)
966 {
967     const char *const str[] = {"#line 10 20\n", "__FILE__"};
968 
969     pp::Token token;
970     lexSingleToken(2, str, &token);
971     EXPECT_EQ(pp::Token::CONST_INT, token.type);
972     EXPECT_EQ("21", token.text);
973 }
974 
975 // Defined operator produced by macro expansion should be parsed inside #if directives
TEST_F(DefineTest,ExpandedDefinedParsedInsideIf)976 TEST_F(DefineTest, ExpandedDefinedParsedInsideIf)
977 {
978     const char *input =
979         "#define bar 1\n"
980         "#define foo defined(bar)\n"
981         "#if foo\n"
982         "bar\n"
983         "#endif\n";
984     const char *expected =
985         "\n"
986         "\n"
987         "\n"
988         "1\n"
989         "\n";
990     preprocess(input, expected);
991 }
992 
993 // Defined operator produced by macro expansion should not be parsed outside #if directives
TEST_F(DefineTest,ExpandedDefinedNotParsedOutsideIf)994 TEST_F(DefineTest, ExpandedDefinedNotParsedOutsideIf)
995 {
996     const char *input =
997         "#define foo defined(bar)\n"
998         "foo\n";
999     const char *expected =
1000         "\n"
1001         "defined(bar)\n";
1002     preprocess(input, expected);
1003 }
1004 
1005 // Test that line directive expressions give errors on negative or undefined shifts.
TEST_F(DefineTest,NegativeShiftInLineDirective)1006 TEST_F(DefineTest, NegativeShiftInLineDirective)
1007 {
1008     const char *input =
1009         "#line 1 << -1\n"
1010         "#line 1 >> -1\n"
1011         "#line 1 << x\n"
1012         "#line 1 >> x\n";
1013     const char *expected =
1014         "\n"
1015         "\n"
1016         "\n"
1017         "\n";
1018 
1019     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_UNDEFINED_SHIFT, _, _)).Times(4);
1020     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INVALID_LINE_NUMBER, _, _)).Times(2);
1021     preprocess(input, expected);
1022 }
1023 
1024 // Undefining a macro in its invocation parameters produces and error
TEST_F(DefineTest,UndefineInInvocation)1025 TEST_F(DefineTest, UndefineInInvocation)
1026 {
1027     const char *input =
1028         "#define G(a, b) a b\n"
1029         "G(\n"
1030         "#undef G\n"
1031         "1, 2)\n";
1032     const char *expected = "\n\n\n1 2\n";
1033 
1034     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED,
1035                                     pp::SourceLocation(0, 3), _));
1036 
1037     preprocess(input, expected);
1038 }
1039 
1040 // Undefining a macro before its invocation parameters produces and error
TEST_F(DefineTest,UndefineInInvocationPreLParen)1041 TEST_F(DefineTest, UndefineInInvocationPreLParen)
1042 {
1043     const char *input =
1044         "#define G(a, b) a b\n"
1045         "G\n"
1046         "#undef G\n"
1047         "(1, 2)\n";
1048     const char *expected = "\n\n\n1 2\n";
1049 
1050     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED,
1051                                     pp::SourceLocation(0, 3), _));
1052 
1053     preprocess(input, expected);
1054 }
1055 
1056 // The name of the macro "a" is inside an incomplete macro invocation of macro "m()" in its own
1057 // expansion. This should not result in infinite recursion.
TEST_F(DefineTest,RecursiveMacroNameInsideIncompleteMacroInvocationInMacroExpansion)1058 TEST_F(DefineTest, RecursiveMacroNameInsideIncompleteMacroInvocationInMacroExpansion)
1059 {
1060     const char *input =
1061         "#define m(a)\n"
1062         "#define a m((a)\n"
1063         "a)\n";
1064     const char *expected =
1065         "\n"
1066         "\n"
1067         "\n";
1068     preprocess(input, expected);
1069 }
1070 
1071 // The name of the macro "a" is inside an incomplete macro invocation of macro "m()" in its own
1072 // expansion. Then the macro "a" is undef'd. This is a regression test for a memory management bug
1073 // where macro "a" would be freed on undef even though cleaning up the recursive macro invocation
1074 // would still need to refer to macro "a".
TEST_F(DefineTest,UndefInsideRecursiveMacroInvocation)1075 TEST_F(DefineTest, UndefInsideRecursiveMacroInvocation)
1076 {
1077     const char *input =
1078         "#define m(a)\n"
1079         "#define a m((a)\n"
1080         "a\n"
1081         "#undef a\n"
1082         ")\n";
1083     const char *expected =
1084         "\n"
1085         "\n"
1086         "\n"
1087         "\n"
1088         "\n";
1089     preprocess(input, expected);
1090 }
1091 
1092 // The macro invocations form a long chain. The macro expander should protect against stack overflow
1093 // and generate an error in this case.
TEST_F(DefineTest,LongMacroInvocationChain)1094 TEST_F(DefineTest, LongMacroInvocationChain)
1095 {
1096     std::stringstream inputStream;
1097     std::stringstream expectedStream;
1098 
1099     inputStream << "#define b(x) x\n";
1100     inputStream << "#define a0(x) foo x\n";
1101     for (int i = 1; i < 20; ++i)
1102     {
1103         inputStream << "#define a" << i << "(x) b(a" << (i - 1) << "(x))\n";
1104     }
1105     inputStream << "a19(y)\n";
1106 
1107     EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP,
1108                                     pp::SourceLocation(0, 22), _));
1109 
1110     pp::PreprocessorSettings settings(SH_GLES2_SPEC);
1111     settings.maxMacroExpansionDepth = 19;
1112 
1113     preprocess(inputStream.str().c_str(), settings);
1114 }
1115 
1116 }  // namespace angle
1117