Path: blob/main_old/src/tests/preprocessor_tests/location_test.cpp
1693 views
//1// Copyright 2012 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "PreprocessorTest.h"7#include "compiler/preprocessor/Token.h"89namespace angle10{1112class LocationTest : public PreprocessorTest13{14protected:15LocationTest() : PreprocessorTest(SH_GLES2_SPEC) {}1617void expectLocation(int count,18const char *const string[],19const int length[],20const pp::SourceLocation &location)21{22ASSERT_TRUE(mPreprocessor.init(count, string, length));2324pp::Token token;25mPreprocessor.lex(&token);26EXPECT_EQ(pp::Token::IDENTIFIER, token.type);27EXPECT_EQ("foo", token.text);2829EXPECT_EQ(location.file, token.location.file);30EXPECT_EQ(location.line, token.location.line);31}32};3334TEST_F(LocationTest, String0_Line1)35{36const char *str = "foo";37pp::SourceLocation loc(0, 1);3839SCOPED_TRACE("String0_Line1");40expectLocation(1, &str, nullptr, loc);41}4243TEST_F(LocationTest, String0_Line2)44{45const char *str = "\nfoo";46pp::SourceLocation loc(0, 2);4748SCOPED_TRACE("String0_Line2");49expectLocation(1, &str, nullptr, loc);50}5152TEST_F(LocationTest, String1_Line1)53{54const char *const str[] = {"\n\n", "foo"};55pp::SourceLocation loc(1, 1);5657SCOPED_TRACE("String1_Line1");58expectLocation(2, str, nullptr, loc);59}6061TEST_F(LocationTest, String1_Line2)62{63const char *const str[] = {"\n\n", "\nfoo"};64pp::SourceLocation loc(1, 2);6566SCOPED_TRACE("String1_Line2");67expectLocation(2, str, nullptr, loc);68}6970TEST_F(LocationTest, NewlineInsideCommentCounted)71{72const char *str = "/*\n\n*/foo";73pp::SourceLocation loc(0, 3);7475SCOPED_TRACE("NewlineInsideCommentCounted");76expectLocation(1, &str, nullptr, loc);77}7879TEST_F(LocationTest, ErrorLocationAfterComment)80{81const char *str = "/*\n\n*/@";8283ASSERT_TRUE(mPreprocessor.init(1, &str, nullptr));84EXPECT_CALL(mDiagnostics,85print(pp::Diagnostics::PP_INVALID_CHARACTER, pp::SourceLocation(0, 3), "@"));8687pp::Token token;88mPreprocessor.lex(&token);89}9091// The location of a token straddling two or more strings is that of the92// first character of the token.9394TEST_F(LocationTest, TokenStraddlingTwoStrings)95{96const char *const str[] = {"f", "oo"};97pp::SourceLocation loc(0, 1);9899SCOPED_TRACE("TokenStraddlingTwoStrings");100expectLocation(2, str, nullptr, loc);101}102103TEST_F(LocationTest, TokenStraddlingThreeStrings)104{105const char *const str[] = {"f", "o", "o"};106pp::SourceLocation loc(0, 1);107108SCOPED_TRACE("TokenStraddlingThreeStrings");109expectLocation(3, str, nullptr, loc);110}111112TEST_F(LocationTest, EndOfFileWithoutNewline)113{114const char *const str[] = {"foo"};115ASSERT_TRUE(mPreprocessor.init(1, str, nullptr));116117pp::Token token;118mPreprocessor.lex(&token);119EXPECT_EQ(pp::Token::IDENTIFIER, token.type);120EXPECT_EQ("foo", token.text);121EXPECT_EQ(0, token.location.file);122EXPECT_EQ(1, token.location.line);123124mPreprocessor.lex(&token);125EXPECT_EQ(pp::Token::LAST, token.type);126EXPECT_EQ(0, token.location.file);127EXPECT_EQ(1, token.location.line);128}129130TEST_F(LocationTest, EndOfFileAfterNewline)131{132const char *const str[] = {"foo\n"};133ASSERT_TRUE(mPreprocessor.init(1, str, nullptr));134135pp::Token token;136mPreprocessor.lex(&token);137EXPECT_EQ(pp::Token::IDENTIFIER, token.type);138EXPECT_EQ("foo", token.text);139EXPECT_EQ(0, token.location.file);140EXPECT_EQ(1, token.location.line);141142mPreprocessor.lex(&token);143EXPECT_EQ(pp::Token::LAST, token.type);144EXPECT_EQ(0, token.location.file);145EXPECT_EQ(2, token.location.line);146}147148TEST_F(LocationTest, EndOfFileAfterEmptyString)149{150const char *const str[] = {"foo\n", "\n", ""};151ASSERT_TRUE(mPreprocessor.init(3, str, nullptr));152153pp::Token token;154mPreprocessor.lex(&token);155EXPECT_EQ(pp::Token::IDENTIFIER, token.type);156EXPECT_EQ("foo", token.text);157EXPECT_EQ(0, token.location.file);158EXPECT_EQ(1, token.location.line);159160mPreprocessor.lex(&token);161EXPECT_EQ(pp::Token::LAST, token.type);162EXPECT_EQ(2, token.location.file);163EXPECT_EQ(1, token.location.line);164}165166TEST_F(LocationTest, ValidLineDirective1)167{168const char *str =169"#line 10\n"170"foo";171pp::SourceLocation loc(0, 10);172173SCOPED_TRACE("ValidLineDirective1");174expectLocation(1, &str, nullptr, loc);175}176177TEST_F(LocationTest, ValidLineDirective2)178{179const char *str =180"#line 10 20\n"181"foo";182pp::SourceLocation loc(20, 10);183184SCOPED_TRACE("ValidLineDirective2");185expectLocation(1, &str, nullptr, loc);186}187188TEST_F(LocationTest, LineDirectiveCommentsIgnored)189{190const char *str =191"/* bar */"192"#"193"/* bar */"194"line"195"/* bar */"196"10"197"/* bar */"198"20"199"/* bar */"200"// bar "201"\n"202"foo";203pp::SourceLocation loc(20, 10);204205SCOPED_TRACE("LineDirectiveCommentsIgnored");206expectLocation(1, &str, nullptr, loc);207}208209TEST_F(LocationTest, LineDirectiveWithMacro1)210{211const char *str =212"#define L 10\n"213"#define F(x) x\n"214"#line L F(20)\n"215"foo";216pp::SourceLocation loc(20, 10);217218SCOPED_TRACE("LineDirectiveWithMacro1");219expectLocation(1, &str, nullptr, loc);220}221222TEST_F(LocationTest, LineDirectiveWithMacro2)223{224const char *str =225"#define LOC 10 20\n"226"#line LOC\n"227"foo";228pp::SourceLocation loc(20, 10);229230SCOPED_TRACE("LineDirectiveWithMacro2");231expectLocation(1, &str, nullptr, loc);232}233234TEST_F(LocationTest, LineDirectiveWithPredefinedMacro)235{236const char *str =237"#line __LINE__ __FILE__\n"238"foo";239pp::SourceLocation loc(0, 1);240241SCOPED_TRACE("LineDirectiveWithMacro");242expectLocation(1, &str, nullptr, loc);243}244245TEST_F(LocationTest, LineDirectiveNewlineBeforeStringBreak)246{247const char *const str[] = {"#line 10 20\n", "foo"};248// String number is incremented after it is set by the line directive.249// Also notice that line number is reset after the string break.250pp::SourceLocation loc(21, 1);251252SCOPED_TRACE("LineDirectiveNewlineBeforeStringBreak");253expectLocation(2, str, nullptr, loc);254}255256TEST_F(LocationTest, LineDirectiveNewlineAfterStringBreak)257{258const char *const str[] = {"#line 10 20", "\nfoo"};259// String number is incremented before it is set by the line directive.260pp::SourceLocation loc(20, 10);261262SCOPED_TRACE("LineDirectiveNewlineAfterStringBreak");263expectLocation(2, str, nullptr, loc);264}265266TEST_F(LocationTest, LineDirectiveMissingNewline)267{268const char *str = "#line 10";269ASSERT_TRUE(mPreprocessor.init(1, &str, nullptr));270271using testing::_;272// Error reported about EOF.273EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_EOF_IN_DIRECTIVE, _, _));274275pp::Token token;276mPreprocessor.lex(&token);277}278279// Test for an error being generated when the line number overflows - regular version280TEST_F(LocationTest, LineOverflowRegular)281{282const char *str = "#line 0x7FFFFFFF\n\n";283284ASSERT_TRUE(mPreprocessor.init(1, &str, nullptr));285286using testing::_;287// Error reported about EOF.288EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));289290pp::Token token;291mPreprocessor.lex(&token);292}293294// Test for an error being generated when the line number overflows - inside /* */ comment version295TEST_F(LocationTest, LineOverflowInComment)296{297const char *str = "#line 0x7FFFFFFF\n/*\n*/";298299ASSERT_TRUE(mPreprocessor.init(1, &str, nullptr));300301using testing::_;302// Error reported about EOF.303EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));304305pp::Token token;306mPreprocessor.lex(&token);307}308309// Test for an error being generated when the line number overflows - inside \n continuation310// version311TEST_F(LocationTest, LineOverflowInContinuationN)312{313const char *str = "#line 0x7FFFFFFF\n \\\n\n";314315ASSERT_TRUE(mPreprocessor.init(1, &str, nullptr));316317using testing::_;318// Error reported about EOF.319EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));320321pp::Token token;322mPreprocessor.lex(&token);323}324325// Test for an error being generated when the line number overflows - inside \r\n continuation326// version327TEST_F(LocationTest, LineOverflowInContinuationRN)328{329const char *str = "#line 0x7FFFFFFF\n \\\r\n\n";330331ASSERT_TRUE(mPreprocessor.init(1, &str, nullptr));332333using testing::_;334// Error reported about EOF.335EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_TOKENIZER_ERROR, _, _));336337pp::Token token;338mPreprocessor.lex(&token);339}340341struct LineTestParam342{343const char *str;344pp::Diagnostics::ID id;345};346347class InvalidLineTest : public LocationTest, public testing::WithParamInterface<LineTestParam>348{};349350TEST_P(InvalidLineTest, Identified)351{352LineTestParam param = GetParam();353ASSERT_TRUE(mPreprocessor.init(1, ¶m.str, nullptr));354355using testing::_;356// Invalid line directive call.357EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));358359pp::Token token;360mPreprocessor.lex(&token);361}362363static const LineTestParam kParams[] = {364{"#line\n", pp::Diagnostics::PP_INVALID_LINE_DIRECTIVE},365{"#line foo\n", pp::Diagnostics::PP_INVALID_LINE_NUMBER},366{"#line defined(foo)\n", pp::Diagnostics::PP_INVALID_LINE_NUMBER},367{"#line 10 foo\n", pp::Diagnostics::PP_INVALID_FILE_NUMBER},368{"#line 10 20 foo\n", pp::Diagnostics::PP_UNEXPECTED_TOKEN},369{"#line 0xffffffff\n", pp::Diagnostics::PP_INTEGER_OVERFLOW},370{"#line 10 0xffffffff\n", pp::Diagnostics::PP_INTEGER_OVERFLOW}};371372INSTANTIATE_TEST_SUITE_P(All, InvalidLineTest, testing::ValuesIn(kParams));373374struct LineExpressionTestParam375{376const char *expression;377int expectedLine;378};379380class LineExpressionTest : public LocationTest,381public testing::WithParamInterface<LineExpressionTestParam>382{};383384TEST_P(LineExpressionTest, ExpressionEvaluation)385{386LineExpressionTestParam param = GetParam();387const char *strs[3] = {"#line ", param.expression, "\nfoo"};388389pp::SourceLocation loc(2, param.expectedLine);390391expectLocation(3, strs, nullptr, loc);392}393394static const LineExpressionTestParam kParamsLineExpressionTest[] = {395{"1 + 2", 3}, {"5 - 3", 2}, {"7 * 11", 77}, {"20 / 10", 2}, {"10 % 5", 0},396{"7 && 3", 1}, {"7 || 0", 1}, {"11 == 11", 1}, {"11 != 11", 0}, {"11 > 7", 1},397{"11 < 7", 0}, {"11 >= 7", 1}, {"11 <= 7", 0}, {"!11", 0}, {"-1", -1},398{"+9", 9}, {"(1 + 2) * 4", 12}, {"3 | 5", 7}, {"3 ^ 5", 6}, {"3 & 5", 1},399{"~5", ~5}, {"2 << 3", 16}, {"16 >> 2", 4}};400401INSTANTIATE_TEST_SUITE_P(All, LineExpressionTest, testing::ValuesIn(kParamsLineExpressionTest));402403} // namespace angle404405406