diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /gfx/angle/src/tests/preprocessor_tests/define_test.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/angle/src/tests/preprocessor_tests/define_test.cpp')
-rwxr-xr-x | gfx/angle/src/tests/preprocessor_tests/define_test.cpp | 988 |
1 files changed, 988 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/preprocessor_tests/define_test.cpp b/gfx/angle/src/tests/preprocessor_tests/define_test.cpp new file mode 100755 index 000000000..e074d1982 --- /dev/null +++ b/gfx/angle/src/tests/preprocessor_tests/define_test.cpp @@ -0,0 +1,988 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "PreprocessorTest.h" +#include "compiler/preprocessor/Token.h" + +using testing::_; + +class DefineTest : public PreprocessorTest +{ +}; + +TEST_F(DefineTest, NonIdentifier) +{ + const char* input = "#define 2 foo\n" + "2\n"; + const char* expected = "\n" + "2\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_UNEXPECTED_TOKEN, + pp::SourceLocation(0, 1), + "2")); + + preprocess(input, expected); +}; + +TEST_F(DefineTest, RedefinePredefined) +{ + const char* input = "#define __LINE__ 10\n" + "__LINE__\n" + "#define __FILE__ 20\n" + "__FILE__\n" + "#define __VERSION__ 200\n" + "__VERSION__\n" + "#define GL_ES 0\n" + "GL_ES\n"; + const char* expected = "\n" + "2\n" + "\n" + "0\n" + "\n" + "100\n" + "\n" + "1\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, + pp::SourceLocation(0, 1), + "__LINE__")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, + pp::SourceLocation(0, 3), + "__FILE__")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, + pp::SourceLocation(0, 5), + "__VERSION__")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, + pp::SourceLocation(0, 7), + "GL_ES")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, ReservedUnderScore1) +{ + const char* input = "#define __foo bar\n" + "__foo\n"; + const char* expected = "\n" + "bar\n"; + + EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, + pp::SourceLocation(0, 1), "__foo")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, ReservedUnderScore2) +{ + const char* input = "#define foo__bar baz\n" + "foo__bar\n"; + const char* expected = "\n" + "baz\n"; + + EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, + pp::SourceLocation(0, 1), "foo__bar")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, ReservedGL) +{ + const char* input = "#define GL_foo bar\n" + "GL_foo\n"; + const char* expected = "\n" + "GL_foo\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_NAME_RESERVED, + pp::SourceLocation(0, 1), + "GL_foo")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjRedefineValid) +{ + const char* input = "#define foo (1-1)\n" + "#define foo /* whitespace */ (1-1) /* other */ \n" + "foo\n"; + const char* expected = "\n" + "\n" + "(1-1)\n"; + // No error or warning. + using testing::_; + EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjRedefineInvalid) +{ + const char* input = "#define foo (0)\n" + "#define foo (1-1)\n" + "foo\n"; + const char* expected = "\n" + "\n" + "(0)\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_REDEFINED, + pp::SourceLocation(0, 2), + "foo")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncRedefineValid) +{ + const char* input = "#define foo(a) ( a )\n" + "#define foo( a )( /* whitespace */ a /* other */ )\n" + "foo(b)\n"; + const char* expected = "\n" + "\n" + "( b )\n"; + // No error or warning. + using testing::_; + EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncRedefineInvalid) +{ + const char* input = "#define foo(b) ( a )\n" + "#define foo(b) ( b )\n" + "foo(1)\n"; + const char* expected = "\n" + "\n" + "( a )\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_REDEFINED, + pp::SourceLocation(0, 2), + "foo")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjBasic) +{ + const char* input = "#define foo 1\n" + "foo\n"; + const char* expected = "\n" + "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjEmpty) +{ + const char* input = "#define foo\n" + "foo\n"; + const char* expected = "\n" + "\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjChain) +{ + const char* input = "#define foo 1\n" + "#define bar foo\n" + "bar\n"; + const char* expected = "\n" + "\n" + "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjChainReverse) +{ + const char* input = "#define bar foo\n" + "#define foo 1\n" + "bar\n"; + const char* expected = "\n" + "\n" + "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjRecursive) +{ + const char* input = "#define foo bar\n" + "#define bar baz\n" + "#define baz foo\n" + "foo\n" + "bar\n" + "baz\n"; + const char* expected = "\n" + "\n" + "\n" + "foo\n" + "bar\n" + "baz\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjCompositeChain) +{ + const char* input = "#define foo 1\n" + "#define bar a foo\n" + "bar\n"; + const char* expected = "\n" + "\n" + "a 1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjCompositeChainReverse) +{ + const char* input = "#define bar a foo\n" + "#define foo 1\n" + "bar\n"; + const char* expected = "\n" + "\n" + "a 1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjCompositeRecursive) +{ + const char* input = "#define foo a bar\n" + "#define bar b baz\n" + "#define baz c foo\n" + "foo\n" + "bar\n" + "baz\n"; + const char* expected = "\n" + "\n" + "\n" + "a b c foo\n" + "b c a bar\n" + "c a b baz\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjChainSelfRecursive) +{ + const char* input = "#define foo foo\n" + "#define bar foo\n" + "bar\n"; + const char* expected = "\n" + "\n" + "foo\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjectLikeWithParens) +{ + const char* input = "#define foo ()1\n" + "foo()\n" + "#define bar ()2\n" + "bar()\n"; + const char* expected = "\n" + "()1()\n" + "\n" + "()2()\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncEmpty) +{ + const char* input = "#define foo()\n" + "foo()\n"; + const char* expected = "\n" + "\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncNoArgs) +{ + const char* input = "#define foo() bar\n" + "foo()\n"; + const char* expected = "\n" + "bar\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncOneArgUnused) +{ + const char* input = "#define foo(x) 1\n" + "foo(bar)\n"; + const char* expected = "\n" + "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncTwoArgsUnused) +{ + const char* input = "#define foo(x,y) 1\n" + "foo(bar,baz)\n"; + const char* expected = "\n" + "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncOneArg) +{ + const char* input = "#define foo(x) ((x)+1)\n" + "foo(bar)\n"; + const char* expected = "\n" + "((bar)+1)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncTwoArgs) +{ + const char* input = "#define foo(x,y) ((x)*(y))\n" + "foo(bar,baz)\n"; + const char* expected = "\n" + "((bar)*(baz))\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncEmptyArgs) +{ + const char* input = "#define zero() pass\n" + "#define one(x) pass\n" + "#define two(x,y) pass\n" + "zero()\n" + "one()\n" + "two(,)\n"; + const char* expected = "\n" + "\n" + "\n" + "pass\n" + "pass\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncMacroAsParam) +{ + const char* input = "#define x 0\n" + "#define foo(x) x\n" + "foo(1)\n"; + const char* expected = "\n" + "\n" + "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncOneArgMulti) +{ + const char* input = "#define foo(x) (x)\n" + "foo(this is a multi-word argument)\n"; + const char* expected = "\n" + "(this is a multi-word argument)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncTwoArgsMulti) +{ + const char* input = "#define foo(x,y) x,two fish,red fish,y\n" + "foo(one fish, blue fish)\n"; + const char* expected = "\n" + "one fish,two fish,red fish,blue fish\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncCompose) +{ + const char* input = "#define bar(x) (1+(x))\n" + "#define foo(y) (2*(y))\n" + "foo(bar(3))\n"; + const char* expected = "\n" + "\n" + "(2*((1+(3))))\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncArgWithParens) +{ + const char* input = "#define foo(x) (x)\n" + "foo(argument(with parens) FTW)\n"; + const char* expected = "\n" + "(argument(with parens) FTW)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncMacroAsNonMacro) +{ + const char* input = "#define foo(bar) bar\n" + "foo bar\n"; + const char* expected = "\n" + "foo bar\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncExtraNewlines) +{ + const char* input = "#define foo(a) (a)\n" + "foo\n" + "(\n" + "1\n" + ")\n"; + const char* expected = "\n" + "\n" + "\n" + "\n" + "(1)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToFunc) +{ + const char* input = "#define foo() pass\n" + "#define bar foo()\n" + "bar\n"; + const char* expected = "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToNonFunc) +{ + const char* input = "#define pass() fail\n" + "#define bar pass\n" + "bar\n"; + const char* expected = "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToFuncWithArgs) +{ + const char* input = "#define foo(fail) fail\n" + "#define bar foo(pass)\n" + "bar\n"; + const char* expected = "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToFuncCompose) +{ + const char* input = "#define baz(fail) fail\n" + "#define bar(fail) fail\n" + "#define foo bar(baz(pass))\n" + "foo\n"; + const char* expected = "\n" + "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToFuncParensInText1) +{ + const char* input = "#define fail() pass\n" + "#define foo fail\n" + "foo()\n"; + const char* expected = "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToFuncParensInText2) +{ + const char* input = "#define bar with,embedded,commas\n" + "#define func(x) pass\n" + "#define foo func\n" + "foo(bar)\n"; + const char* expected = "\n" + "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainObjToFuncMultiLevel) +{ + const char* input = "#define foo(x) pass\n" + "#define bar foo\n" + "#define baz bar\n" + "#define joe baz\n" + "joe (fail)\n"; + const char* expected = "\n" + "\n" + "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ObjToFuncRecursive) +{ + const char* input = "#define A(a,b) B(a,b)\n" + "#define C A(0,C)\n" + "C\n"; + const char* expected = "\n" + "\n" + "B(0,C)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, ChainFuncToFuncCompose) +{ + const char* input = "#define baz(fail) fail\n" + "#define bar(fail) fail\n" + "#define foo() bar(baz(pass))\n" + "foo()\n"; + const char* expected = "\n" + "\n" + "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncSelfRecursive) +{ + const char* input = "#define foo(a) foo(2*(a))\n" + "foo(3)\n"; + const char* expected = "\n" + "foo(2*(3))\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncSelfCompose) +{ + const char* input = "#define foo(a) foo(2*(a))\n" + "foo(foo(3))\n"; + const char* expected = "\n" + "foo(2*(foo(2*(3))))\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncSelfComposeNonFunc) +{ + const char* input = "#define foo(bar) bar\n" + "foo(foo)\n"; + const char* expected = "\n" + "foo\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncSelfComposeNonFuncMultiTokenArg) +{ + const char* input = "#define foo(bar) bar\n" + "foo(1+foo)\n"; + const char* expected = "\n" + "1+foo\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FinalizeUnexpandedMacro) +{ + const char* input = "#define expand(x) expand(x once)\n" + "#define foo(x) x\n" + "foo(expand(just))\n"; + const char* expected = "\n" + "\n" + "expand(just once)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncArgWithCommas) +{ + const char* input = "#define foo(x) pass\n" + "foo(argument (with,embedded, commas) -- baz)\n"; + const char* expected = "\n" + "pass\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncArgObjMaroWithComma) +{ + const char* input = "#define foo(a) (a)\n" + "#define bar two,words\n" + "foo(bar)\n"; + const char* expected = "\n" + "\n" + "(two,words)\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncLeftParenInMacroRightParenInText) +{ + const char* input = "#define bar(a) a*2\n" + "#define foo bar(\n" + "foo b)\n"; + const char* expected = "\n" + "\n" + "b*2\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, RepeatedArg) +{ + const char* input = "#define double(x) x x\n" + "double(1)\n"; + const char* expected = "\n" + "1 1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncMissingRightParen) +{ + const char* input = "#define foo(x) (2*(x))\n" + "foo(3\n"; + const char* expected = "\n" + "\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, + pp::SourceLocation(0, 2), + "foo")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, FuncIncorrectArgCount) +{ + const char* input = "#define foo(x,y) ((x)+(y))\n" + "foo()\n" + "foo(1)\n" + "foo(1,2,3)\n"; + const char* expected = "\n" + "\n" + "\n" + "\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_TOO_FEW_ARGS, + pp::SourceLocation(0, 2), + "foo")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_TOO_FEW_ARGS, + pp::SourceLocation(0, 3), + "foo")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_TOO_MANY_ARGS, + pp::SourceLocation(0, 4), + "foo")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, Undef) +{ + const char* input = "#define foo 1\n" + "foo\n" + "#undef foo\n" + "foo\n"; + const char* expected = "\n" + "1\n" + "\n" + "foo\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, UndefPredefined) +{ + const char* input = "#undef __LINE__\n" + "__LINE__\n" + "#undef __FILE__\n" + "__FILE__\n" + "#undef __VERSION__\n" + "__VERSION__\n" + "#undef GL_ES\n" + "GL_ES\n"; + const char* expected = "\n" + "2\n" + "\n" + "0\n" + "\n" + "100\n" + "\n" + "1\n"; + + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, + pp::SourceLocation(0, 1), + "__LINE__")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, + pp::SourceLocation(0, 3), + "__FILE__")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, + pp::SourceLocation(0, 5), + "__VERSION__")); + EXPECT_CALL(mDiagnostics, + print(pp::Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, + pp::SourceLocation(0, 7), + "GL_ES")); + + preprocess(input, expected); +} + +TEST_F(DefineTest, UndefRedefine) +{ + const char* input = "#define foo 1\n" + "foo\n" + "#undef foo\n" + "foo\n" + "#define foo 2\n" + "foo\n"; + const char* expected = "\n" + "1\n" + "\n" + "foo\n" + "\n" + "2\n"; + + preprocess(input, expected); +} + +// Example from C99 standard section 6.10.3.5 Scope of macro definitions +TEST_F(DefineTest, C99Example) +{ + const char* input = + "#define x 3 \n" + "#define f(a) f(x * (a)) \n" + "#undef x \n" + "#define x 2 \n" + "#define g f \n" + "#define z z[0] \n" + "#define h g(~ \n" + "#define m(a) a(w) \n" + "#define w 0,1 \n" + "#define t(a) a \n" + "#define p() int \n" + "#define q(x) x \n" + " \n" + "f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);\n" + "g(x+(3,4)-w) | h 5) & m\n" + " (f)^m(m);\n" + "p() i[q()] = { q(1), 23, 4, 5, };\n"; + const char* expected = + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);\n" + "f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) &\n" + " f(2 * (0,1))^m(0,1);\n" + "int i[] = { 1, 23, 4, 5, };\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, Predefined_GL_ES) +{ + const char* input = "GL_ES\n"; + const char* expected = "1\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, Predefined_VERSION) +{ + const char* input = "__VERSION__\n"; + const char* expected = "100\n"; + + preprocess(input, expected); +} + +TEST_F(DefineTest, Predefined_LINE1) +{ + const char* str = "\n\n__LINE__"; + ASSERT_TRUE(mPreprocessor.init(1, &str, NULL)); + + pp::Token token; + mPreprocessor.lex(&token); + EXPECT_EQ(pp::Token::CONST_INT, token.type); + EXPECT_EQ("3", token.text); +} + +TEST_F(DefineTest, Predefined_LINE2) +{ + const char* str = "#line 10\n" + "__LINE__\n"; + ASSERT_TRUE(mPreprocessor.init(1, &str, NULL)); + + pp::Token token; + mPreprocessor.lex(&token); + EXPECT_EQ(pp::Token::CONST_INT, token.type); + EXPECT_EQ("10", token.text); +} + +TEST_F(DefineTest, Predefined_FILE1) +{ + const char* const str[] = {"", "", "__FILE__"}; + ASSERT_TRUE(mPreprocessor.init(3, str, NULL)); + + pp::Token token; + mPreprocessor.lex(&token); + EXPECT_EQ(pp::Token::CONST_INT, token.type); + EXPECT_EQ("2", token.text); +} + +TEST_F(DefineTest, Predefined_FILE2) +{ + const char* const str[] = {"#line 10 20\n", "__FILE__"}; + ASSERT_TRUE(mPreprocessor.init(2, str, NULL)); + + pp::Token token; + mPreprocessor.lex(&token); + EXPECT_EQ(pp::Token::CONST_INT, token.type); + EXPECT_EQ("21", token.text); +} + +// Defined operator produced by macro expansion should be parsed inside #if directives +TEST_F(DefineTest, ExpandedDefinedParsedInsideIf) +{ + const char *input = + "#define bar 1\n" + "#define foo defined(bar)\n" + "#if foo\n" + "bar\n" + "#endif\n"; + const char *expected = + "\n" + "\n" + "\n" + "1\n" + "\n"; + preprocess(input, expected); +} + +// Defined operator produced by macro expansion should not be parsed outside #if directives +TEST_F(DefineTest, ExpandedDefinedNotParsedOutsideIf) +{ + const char *input = + "#define foo defined(bar)\n" + "foo\n"; + const char *expected = + "\n" + "defined(bar)\n"; + preprocess(input, expected); +} + +// Test that line directive expressions give errors on negative or undefined shifts. +TEST_F(DefineTest, NegativeShiftInLineDirective) +{ + const char *input = + "#line 1 << -1\n" + "#line 1 >> -1\n" + "#line 1 << x\n" + "#line 1 >> x\n"; + const char *expected = + "\n" + "\n" + "\n" + "\n"; + + EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_UNDEFINED_SHIFT, _, _)).Times(4); + EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_INVALID_LINE_NUMBER, _, _)).Times(2); + preprocess(input, expected); +} + +// Undefining a macro in its invocation parameters produces and error +TEST_F(DefineTest, UndefineInInvocation) +{ + const char *input = + "#define G(a, b) a b\n" + "G(\n" + "#undef G\n" + "1, 2)\n"; + const char *expected = "\n\n\n1 2\n"; + + EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, + pp::SourceLocation(0, 3), _)); + + preprocess(input, expected); +} + +// Undefining a macro before its invocation parameters produces and error +TEST_F(DefineTest, UndefineInInvocationPreLParen) +{ + const char *input = + "#define G(a, b) a b\n" + "G\n" + "#undef G\n" + "(1, 2)\n"; + const char *expected = "\n\n\n1 2\n"; + + EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, + pp::SourceLocation(0, 3), _)); + + preprocess(input, expected); +} + +// The name of the macro "a" is inside an incomplete macro invocation of macro "m()" in its own +// expansion. This should not result in infinite recursion. +TEST_F(DefineTest, RecursiveMacroNameInsideIncompleteMacroInvocationInMacroExpansion) +{ + const char *input = + "#define m(a)\n" + "#define a m((a)\n" + "a)\n"; + const char *expected = + "\n" + "\n" + "\n"; + preprocess(input, expected); +} |