Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/preprocessor_tests/define_test.cpp
1693 views
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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.
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".
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.
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
1118