diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y')
-rw-r--r-- | src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y | 151 |
1 files changed, 121 insertions, 30 deletions
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y index 8caf36bfc8..7b5d9e9cee 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y +++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y @@ -28,7 +28,7 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser. #pragma GCC diagnostic ignored "-Wuninitialized" #endif #elif defined(_MSC_VER) -#pragma warning(disable: 4065 4701 4702) +#pragma warning(disable: 4065 4244 4701 4702) #endif #include "ExpressionParser.h" @@ -52,6 +52,7 @@ typedef __int64 YYSTYPE; #include <stdint.h> typedef intmax_t YYSTYPE; #endif // _MSC_VER + #define YYENABLE_NLS 0 #define YYLTYPE_IS_TRIVIAL 1 #define YYSTYPE_IS_TRIVIAL 1 @@ -64,6 +65,17 @@ struct Context pp::Lexer* lexer; pp::Token* token; int* result; + bool parsePresetToken; + + pp::ExpressionParser::ErrorSettings errorSettings; + bool *valid; + + void startIgnoreErrors() { ++ignoreErrors; } + void endIgnoreErrors() { --ignoreErrors; } + + bool isIgnoringErrors() { return ignoreErrors > 0; } + + int ignoreErrors; }; } // namespace %} @@ -79,6 +91,7 @@ static void yyerror(Context* context, const char* reason); %} %token TOK_CONST_INT +%token TOK_IDENTIFIER %left TOK_OP_OR %left TOK_OP_AND %left '|' @@ -102,11 +115,58 @@ input expression : TOK_CONST_INT - | expression TOK_OP_OR expression { - $$ = $1 || $3; + | TOK_IDENTIFIER { + if (!context->isIgnoringErrors()) + { + // This rule should be applied right after the token is lexed, so we can + // refer to context->token in the error message. + context->diagnostics->report(context->errorSettings.unexpectedIdentifier, + context->token->location, context->token->text); + *(context->valid) = false; + } + $$ = $1; } - | expression TOK_OP_AND expression { - $$ = $1 && $3; + | expression TOK_OP_OR { + if ($1 != 0) + { + // Ignore errors in the short-circuited part of the expression. + // ESSL3.00 section 3.4: + // If an operand is not evaluated, the presence of undefined identifiers + // in the operand will not cause an error. + // Unevaluated division by zero should not cause an error either. + context->startIgnoreErrors(); + } + } expression { + if ($1 != 0) + { + context->endIgnoreErrors(); + $$ = static_cast<YYSTYPE>(1); + } + else + { + $$ = $1 || $4; + } + } + | expression TOK_OP_AND { + if ($1 == 0) + { + // Ignore errors in the short-circuited part of the expression. + // ESSL3.00 section 3.4: + // If an operand is not evaluated, the presence of undefined identifiers + // in the operand will not cause an error. + // Unevaluated division by zero should not cause an error either. + context->startIgnoreErrors(); + } + } expression { + if ($1 == 0) + { + context->endIgnoreErrors(); + $$ = static_cast<YYSTYPE>(0); + } + else + { + $$ = $1 && $4; + } } | expression '|' expression { $$ = $1 | $3; @@ -148,28 +208,42 @@ expression $$ = $1 + $3; } | expression '%' expression { - if ($3 == 0) { - std::ostringstream stream; - stream << $1 << " % " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { + if ($3 == 0) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " % " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast<YYSTYPE>(0); + } + else + { $$ = $1 % $3; } } | expression '/' expression { - if ($3 == 0) { - std::ostringstream stream; - stream << $1 << " / " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { + if ($3 == 0) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " / " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast<YYSTYPE>(0); + } + else + { $$ = $1 / $3; } } @@ -197,22 +271,35 @@ expression int yylex(YYSTYPE *lvalp, Context *context) { + pp::Token *token = context->token; + if (!context->parsePresetToken) + { + context->lexer->lex(token); + } + context->parsePresetToken = false; + int type = 0; - pp::Token *token = context->token; switch (token->type) { case pp::Token::CONST_INT: { unsigned int val = 0; - if (!token->uValue(&val)) + int testVal = 0; + if (!token->uValue(&val) || (!token->iValue(&testVal) && + context->errorSettings.integerLiteralsMustFit32BitSignedRange)) { context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); + *(context->valid) = false; } *lvalp = static_cast<YYSTYPE>(val); type = TOK_CONST_INT; break; } + case pp::Token::IDENTIFIER: + *lvalp = static_cast<YYSTYPE>(-1); + type = TOK_IDENTIFIER; + break; case pp::Token::OP_OR: type = TOK_OP_OR; break; @@ -258,10 +345,6 @@ int yylex(YYSTYPE *lvalp, Context *context) break; } - // Advance to the next token if the current one is valid. - if (type != 0) - context->lexer->lex(token); - return type; } @@ -280,13 +363,21 @@ ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics) { } -bool ExpressionParser::parse(Token *token, int *result) +bool ExpressionParser::parse(Token *token, + int *result, + bool parsePresetToken, + const ErrorSettings &errorSettings, + bool *valid) { Context context; context.diagnostics = mDiagnostics; context.lexer = mLexer; context.token = token; context.result = result; + context.ignoreErrors = 0; + context.parsePresetToken = parsePresetToken; + context.errorSettings = errorSettings; + context.valid = valid; int ret = yyparse(&context); switch (ret) { |