summaryrefslogtreecommitdiff
path: root/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp')
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp555
1 files changed, 370 insertions, 185 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp
index 1fae00945..a8df2351e 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp
@@ -1,10 +1,10 @@
-/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */
+/* A Bison parser, made by GNU Bison 3.0.4. */
-/* A Bison parser, made by GNU Bison 3.0.1. */
+/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.1"
+#define YYBISON_VERSION "3.0.4"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -88,7 +88,7 @@
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
#elif defined(_MSC_VER)
-#pragma warning(disable: 4065 4701)
+#pragma warning(disable: 4065 4244 4701 4702)
#endif
#include "ExpressionParser.h"
@@ -101,17 +101,16 @@
#include <cassert>
#include <sstream>
+#include <stdint.h>
#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"
+#include "common/mathutil.h"
+
+typedef int32_t YYSTYPE;
+typedef uint32_t UNSIGNED_TYPE;
-#if defined(_MSC_VER)
-typedef __int64 YYSTYPE;
-#else
-#include <stdint.h>
-typedef intmax_t YYSTYPE;
-#endif // _MSC_VER
#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
@@ -124,6 +123,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
@@ -164,15 +174,16 @@ extern int ppdebug;
enum yytokentype
{
TOK_CONST_INT = 258,
- TOK_OP_OR = 259,
- TOK_OP_AND = 260,
- TOK_OP_EQ = 261,
- TOK_OP_NE = 262,
- TOK_OP_LE = 263,
- TOK_OP_GE = 264,
- TOK_OP_LEFT = 265,
- TOK_OP_RIGHT = 266,
- TOK_UNARY = 267
+ TOK_IDENTIFIER = 259,
+ TOK_OP_OR = 260,
+ TOK_OP_AND = 261,
+ TOK_OP_EQ = 262,
+ TOK_OP_NE = 263,
+ TOK_OP_LE = 264,
+ TOK_OP_GE = 265,
+ TOK_OP_LEFT = 266,
+ TOK_OP_RIGHT = 267,
+ TOK_UNARY = 268
};
#endif
@@ -431,23 +442,23 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 14
+#define YYFINAL 15
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 175
+#define YYLAST 176
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 27
+#define YYNTOKENS 28
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 3
+#define YYNNTS 5
/* YYNRULES -- Number of rules. */
-#define YYNRULES 26
+#define YYNRULES 29
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 52
+#define YYNSTATES 55
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 267
+#define YYMAXUTOK 268
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -459,16 +470,16 @@ static const yytype_uint8 yytranslate[] =
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 23, 2, 2, 2, 21, 8, 2,
- 25, 26, 19, 17, 2, 18, 2, 20, 2, 2,
+ 2, 2, 2, 24, 2, 2, 2, 22, 9, 2,
+ 26, 27, 20, 18, 2, 19, 2, 21, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 11, 2, 12, 2, 2, 2, 2, 2, 2, 2,
+ 12, 2, 13, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 7, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 8, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 6, 2, 24, 2, 2, 2,
+ 2, 2, 2, 2, 7, 2, 25, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -482,16 +493,16 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 9, 10, 13, 14, 15, 16, 22
+ 5, 6, 10, 11, 14, 15, 16, 17, 23
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
+static const yytype_uint16 yyrline[] =
{
- 0, 97, 97, 104, 105, 108, 111, 114, 117, 120,
- 123, 126, 129, 132, 135, 138, 141, 144, 147, 150,
- 163, 176, 179, 182, 185, 188, 191
+ 0, 108, 108, 115, 116, 127, 127, 148, 148, 169,
+ 172, 175, 178, 181, 184, 187, 190, 193, 196, 221,
+ 246, 249, 252, 272, 299, 302, 305, 308, 320, 323
};
#endif
@@ -500,11 +511,11 @@ static const yytype_uint8 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR",
- "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE", "'<'",
- "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT", "'+'",
- "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'",
- "$accept", "input", "expression", YY_NULLPTR
+ "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER",
+ "TOK_OP_OR", "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE",
+ "'<'", "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT",
+ "'+'", "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('",
+ "')'", "$accept", "input", "expression", "$@1", "$@2", YY_NULLPTR
};
#endif
@@ -513,16 +524,16 @@ static const char *const yytname[] =
(internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
- 0, 256, 257, 258, 259, 260, 124, 94, 38, 261,
- 262, 60, 62, 263, 264, 265, 266, 43, 45, 42,
- 47, 37, 267, 33, 126, 40, 41
+ 0, 256, 257, 258, 259, 260, 261, 124, 94, 38,
+ 262, 263, 60, 62, 264, 265, 266, 267, 43, 45,
+ 42, 47, 37, 268, 33, 126, 40, 41
};
# endif
-#define YYPACT_NINF -11
+#define YYPACT_NINF -12
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-11)))
+ (!!((Yystate) == (-12)))
#define YYTABLE_NINF -1
@@ -533,12 +544,12 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 46, -11, 46, 46, 46, 46, 46, 12, 68, -11,
- -11, -11, -11, 27, -11, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, -11, 85, 101, 116, 130, 143, 154,
- 154, -10, -10, -10, -10, 37, 37, 31, 31, -11,
- -11, -11
+ 31, -12, -12, 31, 31, 31, 31, 31, 51, 76,
+ -12, -12, -12, -12, 53, -12, -12, -12, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, -12, 31, 31, 124, 138, 26,
+ 149, 149, -11, -11, -11, -11, 154, 154, -8, -8,
+ -12, -12, -12, 93, 109
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -546,24 +557,24 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 3, 0, 0, 0, 0, 0, 0, 2, 25,
- 24, 22, 23, 0, 1, 0, 0, 0, 0, 0,
+ 0, 3, 4, 0, 0, 0, 0, 0, 0, 2,
+ 28, 27, 25, 26, 0, 1, 5, 7, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 26, 4, 5, 6, 7, 8, 10,
- 9, 14, 13, 12, 11, 16, 15, 18, 17, 21,
- 20, 19
+ 0, 0, 0, 0, 29, 0, 0, 9, 10, 11,
+ 13, 12, 17, 16, 15, 14, 19, 18, 21, 20,
+ 24, 23, 22, 6, 8
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -11, -11, -2
+ -12, -12, -3, -12, -12
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 7, 8
+ -1, 8, 9, 35, 36
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -571,74 +582,74 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 9, 10, 11, 12, 13, 26, 27, 28, 29, 30,
- 31, 32, 14, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 1,
- 30, 31, 32, 33, 28, 29, 30, 31, 32, 0,
- 0, 0, 0, 2, 3, 0, 0, 0, 0, 4,
- 5, 6, 15, 16, 17, 18, 19, 20, 21, 22,
+ 10, 11, 12, 13, 14, 27, 28, 29, 30, 31,
+ 32, 33, 31, 32, 33, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 0, 53, 54, 1, 2, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 3,
+ 4, 15, 0, 0, 0, 5, 6, 7, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 0, 0, 0, 0,
+ 34, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32
+ 33, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 29, 30, 31, 32, 33
};
static const yytype_int8 yycheck[] =
{
- 2, 3, 4, 5, 6, 15, 16, 17, 18, 19,
- 20, 21, 0, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 3,
- 19, 20, 21, 26, 17, 18, 19, 20, 21, -1,
- -1, -1, -1, 17, 18, -1, -1, -1, -1, 23,
- 24, 25, 4, 5, 6, 7, 8, 9, 10, 11,
+ 3, 4, 5, 6, 7, 16, 17, 18, 19, 20,
+ 21, 22, 20, 21, 22, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, -1, 35, 36, 3, 4, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 18,
+ 19, 0, -1, -1, -1, 24, 25, 26, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, -1, -1, -1, -1,
+ 27, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21
+ 22, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 18, 19, 20, 21, 22
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 17, 18, 23, 24, 25, 28, 29, 29,
- 29, 29, 29, 29, 0, 4, 5, 6, 7, 8,
+ 0, 3, 4, 18, 19, 24, 25, 26, 29, 30,
+ 30, 30, 30, 30, 30, 0, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 26, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29
+ 19, 20, 21, 22, 27, 31, 32, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 27, 28, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29
+ 0, 28, 29, 30, 30, 31, 30, 32, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
- 0, 2, 1, 1, 3, 3, 3, 3, 3, 3,
+ 0, 2, 1, 1, 1, 0, 4, 0, 4, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 2, 2, 2, 2, 3
+ 3, 3, 3, 3, 3, 2, 2, 2, 2, 3
};
@@ -1332,7 +1343,15 @@ yyreduce:
case 4:
{
- (yyval) = (yyvsp[-2]) || (yyvsp[0]);
+ 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;
+ }
+ (yyval) = (yyvsp[0]);
}
break;
@@ -1340,7 +1359,15 @@ yyreduce:
case 5:
{
- (yyval) = (yyvsp[-2]) && (yyvsp[0]);
+ if ((yyvsp[-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();
+ }
}
break;
@@ -1348,7 +1375,15 @@ yyreduce:
case 6:
{
- (yyval) = (yyvsp[-2]) | (yyvsp[0]);
+ if ((yyvsp[-3]) != 0)
+ {
+ context->endIgnoreErrors();
+ (yyval) = static_cast<YYSTYPE>(1);
+ }
+ else
+ {
+ (yyval) = (yyvsp[-3]) || (yyvsp[0]);
+ }
}
break;
@@ -1356,7 +1391,15 @@ yyreduce:
case 7:
{
- (yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
+ if ((yyvsp[-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();
+ }
}
break;
@@ -1364,7 +1407,15 @@ yyreduce:
case 8:
{
- (yyval) = (yyvsp[-2]) & (yyvsp[0]);
+ if ((yyvsp[-3]) == 0)
+ {
+ context->endIgnoreErrors();
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else
+ {
+ (yyval) = (yyvsp[-3]) && (yyvsp[0]);
+ }
}
break;
@@ -1372,7 +1423,7 @@ yyreduce:
case 9:
{
- (yyval) = (yyvsp[-2]) != (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) | (yyvsp[0]);
}
break;
@@ -1380,7 +1431,7 @@ yyreduce:
case 10:
{
- (yyval) = (yyvsp[-2]) == (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
}
break;
@@ -1388,7 +1439,7 @@ yyreduce:
case 11:
{
- (yyval) = (yyvsp[-2]) >= (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) & (yyvsp[0]);
}
break;
@@ -1396,7 +1447,7 @@ yyreduce:
case 12:
{
- (yyval) = (yyvsp[-2]) <= (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) != (yyvsp[0]);
}
break;
@@ -1404,7 +1455,7 @@ yyreduce:
case 13:
{
- (yyval) = (yyvsp[-2]) > (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) == (yyvsp[0]);
}
break;
@@ -1412,7 +1463,7 @@ yyreduce:
case 14:
{
- (yyval) = (yyvsp[-2]) < (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) >= (yyvsp[0]);
}
break;
@@ -1420,7 +1471,7 @@ yyreduce:
case 15:
{
- (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) <= (yyvsp[0]);
}
break;
@@ -1428,7 +1479,7 @@ yyreduce:
case 16:
{
- (yyval) = (yyvsp[-2]) << (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) > (yyvsp[0]);
}
break;
@@ -1436,7 +1487,7 @@ yyreduce:
case 17:
{
- (yyval) = (yyvsp[-2]) - (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) < (yyvsp[0]);
}
break;
@@ -1444,7 +1495,29 @@ yyreduce:
case 18:
{
- (yyval) = (yyvsp[-2]) + (yyvsp[0]);
+ if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " >> " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else if ((yyvsp[-2]) < 0)
+ {
+ // Logical shift right.
+ (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) >> (yyvsp[0]));
+ }
+ else
+ {
+ (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
+ }
}
break;
@@ -1452,16 +1525,28 @@ yyreduce:
case 19:
{
- if ((yyvsp[0]) == 0) {
- std::ostringstream stream;
- stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
- std::string text = stream.str();
- context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
- context->token->location,
- text.c_str());
- YYABORT;
- } else {
- (yyval) = (yyvsp[-2]) % (yyvsp[0]);
+ if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " << " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else if ((yyvsp[-2]) < 0)
+ {
+ // Logical shift left.
+ (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
+ }
+ else
+ {
+ (yyval) = (yyvsp[-2]) << (yyvsp[0]);
}
}
@@ -1470,17 +1555,7 @@ yyreduce:
case 20:
{
- if ((yyvsp[0]) == 0) {
- std::ostringstream stream;
- stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
- std::string text = stream.str();
- context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
- context->token->location,
- text.c_str());
- YYABORT;
- } else {
- (yyval) = (yyvsp[-2]) / (yyvsp[0]);
- }
+ (yyval) = gl::WrappingDiff<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
}
break;
@@ -1488,7 +1563,7 @@ yyreduce:
case 21:
{
- (yyval) = (yyvsp[-2]) * (yyvsp[0]);
+ (yyval) = gl::WrappingSum<YYSTYPE>((yyvsp[-2]), (yyvsp[0]));
}
break;
@@ -1496,7 +1571,24 @@ yyreduce:
case 22:
{
- (yyval) = ! (yyvsp[0]);
+ if ((yyvsp[0]) == 0)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else
+ {
+ (yyval) = (yyvsp[-2]) % (yyvsp[0]);
+ }
}
break;
@@ -1504,7 +1596,31 @@ yyreduce:
case 23:
{
- (yyval) = ~ (yyvsp[0]);
+ if ((yyvsp[0]) == 0)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else if ((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min() && (yyvsp[0]) == -1)
+ {
+ // Check for the special case where the minimum representable number is
+ // divided by -1. If left alone this leads to integer overflow in C++, which
+ // has undefined results.
+ (yyval) = std::numeric_limits<YYSTYPE>::max();
+ }
+ else
+ {
+ (yyval) = (yyvsp[-2]) / (yyvsp[0]);
+ }
}
break;
@@ -1512,7 +1628,7 @@ yyreduce:
case 24:
{
- (yyval) = - (yyvsp[0]);
+ (yyval) = gl::WrappingMul((yyvsp[-2]), (yyvsp[0]));
}
break;
@@ -1520,7 +1636,7 @@ yyreduce:
case 25:
{
- (yyval) = + (yyvsp[0]);
+ (yyval) = ! (yyvsp[0]);
}
break;
@@ -1528,6 +1644,39 @@ yyreduce:
case 26:
{
+ (yyval) = ~ (yyvsp[0]);
+ }
+
+ break;
+
+ case 27:
+
+ {
+ // Check for negation of minimum representable integer to prevent undefined signed int
+ // overflow.
+ if ((yyvsp[0]) == std::numeric_limits<YYSTYPE>::min())
+ {
+ (yyval) = std::numeric_limits<YYSTYPE>::min();
+ }
+ else
+ {
+ (yyval) = -(yyvsp[0]);
+ }
+ }
+
+ break;
+
+ case 28:
+
+ {
+ (yyval) = + (yyvsp[0]);
+ }
+
+ break;
+
+ case 29:
+
+ {
(yyval) = (yyvsp[-1]);
}
@@ -1765,79 +1914,115 @@ yyreturn:
-int yylex(YYSTYPE* lvalp, Context* context)
+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:
- {
+ 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::INTEGER_OVERFLOW,
+ 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::OP_OR: type = TOK_OP_OR; break;
- case pp::Token::OP_AND: type = TOK_OP_AND; break;
- case pp::Token::OP_NE: type = TOK_OP_NE; break;
- case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
- case pp::Token::OP_GE: type = TOK_OP_GE; break;
- case pp::Token::OP_LE: type = TOK_OP_LE; break;
- case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
- case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
- case '|': type = '|'; break;
- case '^': type = '^'; break;
- case '&': type = '&'; break;
- case '>': type = '>'; break;
- case '<': type = '<'; break;
- case '-': type = '-'; break;
- case '+': type = '+'; break;
- case '%': type = '%'; break;
- case '/': type = '/'; break;
- case '*': type = '*'; break;
- case '!': type = '!'; break;
- case '~': type = '~'; break;
- case '(': type = '('; break;
- case ')': type = ')'; break;
+ case pp::Token::IDENTIFIER:
+ *lvalp = static_cast<YYSTYPE>(-1);
+ type = TOK_IDENTIFIER;
+ break;
+ case pp::Token::OP_OR:
+ type = TOK_OP_OR;
+ break;
+ case pp::Token::OP_AND:
+ type = TOK_OP_AND;
+ break;
+ case pp::Token::OP_NE:
+ type = TOK_OP_NE;
+ break;
+ case pp::Token::OP_EQ:
+ type = TOK_OP_EQ;
+ break;
+ case pp::Token::OP_GE:
+ type = TOK_OP_GE;
+ break;
+ case pp::Token::OP_LE:
+ type = TOK_OP_LE;
+ break;
+ case pp::Token::OP_RIGHT:
+ type = TOK_OP_RIGHT;
+ break;
+ case pp::Token::OP_LEFT:
+ type = TOK_OP_LEFT;
+ break;
+ case '|':
+ case '^':
+ case '&':
+ case '>':
+ case '<':
+ case '-':
+ case '+':
+ case '%':
+ case '/':
+ case '*':
+ case '!':
+ case '~':
+ case '(':
+ case ')':
+ type = token->type;
+ break;
- default: break;
+ default:
+ break;
}
- // Advance to the next token if the current one is valid.
- if (type != 0) context->lexer->lex(token);
-
return type;
}
-void yyerror(Context* context, const char* reason)
+void yyerror(Context *context, const char *reason)
{
- context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
+ context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION,
context->token->location,
reason);
}
namespace pp {
-ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
- mLexer(lexer),
- mDiagnostics(diagnostics)
+ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
+ : mLexer(lexer),
+ mDiagnostics(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)
{
@@ -1846,12 +2031,12 @@ bool ExpressionParser::parse(Token* token, int* result)
break;
case 2:
- mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
break;
default:
assert(false);
- mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
+ mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
break;
}