Fixes to scanning:
- do version checking for the line-continuation character
- check for built-in names in #undef
- bug fix for #elif after #else
- do version checking for use of floating point suffixes (f, LF, etc.)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24011 e7fa87d3-cd2b-0410-9028-fcbf551c1848
diff --git a/Install/Windows/glslangValidator.exe b/Install/Windows/glslangValidator.exe
index b647163..ebdec87 100644
--- a/Install/Windows/glslangValidator.exe
+++ b/Install/Windows/glslangValidator.exe
Binary files differ
diff --git a/Test/100.frag b/Test/100.frag
index cb78f8b..9daa026 100644
--- a/Test/100.frag
+++ b/Test/100.frag
@@ -146,4 +146,7 @@
return a;
}
+float f123 = 4.0f; // ERROR
+float f124 = 5e10F; // ERROR
+
uniform samplerExternalOES badExt; // syntax ERROR
diff --git a/Test/120.frag b/Test/120.frag
index e6ed62a..ac70c20 100644
--- a/Test/120.frag
+++ b/Test/120.frag
@@ -36,7 +36,7 @@
f += a;
f = a - f;
v3 *= iv3;
- v3 = iv3 / 2.0;
+ v3 = iv3 / 2.0f;
v3 = 3.0 * iv3;
v3 = 2 * v3;
v3 = v3 - 2;
@@ -102,7 +102,7 @@
bool gen(vec3 v)
{
- if (abs(v[0]) < 1e-4 && abs(v[1]) < 1e-4)
+ if (abs(v[0]) < 1e-4F && abs(v[1]) < 1e-4)
return true;
}
diff --git a/Test/300.vert b/Test/300.vert
index 1d9d631..cdbfa8e 100644
--- a/Test/300.vert
+++ b/Test/300.vert
@@ -65,7 +65,7 @@
int a[]; // ERROR
} ubInst[]; // ERROR
void foo(int a[]); // ERROR
-float okayA[] = float[](3.0, 4.0); // Okay
+float okayA[] = float[](3.0f, 4.0F); // Okay
out vec3 newV;
void newVFun()
diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out
index 2507e06..1c08f35 100644
--- a/Test/baseResults/100.frag.out
+++ b/Test/baseResults/100.frag.out
@@ -57,8 +57,10 @@
ERROR: 0:138: 'bitwise inclusive or' : not supported for this version or the enabled extensions
ERROR: 0:139: 'bitwise and' : not supported for this version or the enabled extensions
ERROR: 0:144: 'a' : redefinition
-ERROR: 0:149: '' : syntax error
-ERROR: 53 compilation errors. No code generated.
+ERROR: 0:149: 'floating-point suffix' : not supported for this version or the enabled extensions
+ERROR: 0:150: 'floating-point suffix' : not supported for this version or the enabled extensions
+ERROR: 0:152: '' : syntax error
+ERROR: 55 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:3 Sequence
@@ -245,6 +247,16 @@
0:146 Sequence
0:146 Branch: Return with expression
0:146 'a' (in mediump int)
+0:149 Sequence
+0:149 move second child to first child (mediump float)
+0:149 'f123' (mediump float)
+0:149 Constant:
+0:149 4.000000
+0:150 Sequence
+0:150 move second child to first child (mediump float)
+0:150 'f124' (mediump float)
+0:150 Constant:
+0:150 50000000000.000000
0:? Linker Objects
0:? 'a' (3-element array of mediump int)
0:? 'uint' (mediump int)
@@ -264,4 +276,6 @@
0:? 'sExt' (uniform lowp samplerExternalOES)
0:? 'mediumExt' (uniform mediump samplerExternalOES)
0:? 'highExt' (uniform highp samplerExternalOES)
+0:? 'f123' (mediump float)
+0:? 'f124' (mediump float)
diff --git a/Test/baseResults/cppNest.vert.out b/Test/baseResults/cppNest.vert.out
index 918f832..95f28f4 100644
--- a/Test/baseResults/cppNest.vert.out
+++ b/Test/baseResults/cppNest.vert.out
@@ -35,6 +35,24 @@
0:86 'gl_Position' (gl_Position 4-component vector of float)
0:86 Construct vec4 (4-component vector of float)
0:86 'sum' (float)
+0:103 Sequence
+0:103 move second child to first child (int)
+0:103 'selected4' (int)
+0:103 Constant:
+0:103 4 (const int)
+0:115 Sequence
+0:115 move second child to first child (int)
+0:115 'selected2' (int)
+0:115 Constant:
+0:115 2 (const int)
+0:133 Sequence
+0:133 move second child to first child (int)
+0:133 'selected3' (int)
+0:133 Constant:
+0:133 3 (const int)
0:? Linker Objects
0:? 'sum' (float)
+0:? 'selected4' (int)
+0:? 'selected2' (int)
+0:? 'selected3' (int)
diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out
index a0c313c..a5d18f2 100644
--- a/Test/baseResults/cppSimple.vert.out
+++ b/Test/baseResults/cppSimple.vert.out
@@ -24,11 +24,11 @@
ERROR: 0:136: '=' : cannot convert from 'const float' to 'int'
ERROR: 0:138: ''' : character literals not supported
ERROR: 0:138: ''' : character literals not supported
-ERROR: 0:141: '#define' : reserved built-in name prefix: GL_
-ERROR: 0:142: '#define' : reserved built-in name prefix: GL_
-ERROR: 0:143: '#define' : names containing consecutive underscores are reserved
-ERROR: 0:144: '#define' : names containing consecutive underscores are reserved
-ERROR: 0:145: '#define' : names containing consecutive underscores are reserved
+ERROR: 0:141: '#define' : can't use with built-in names ("GL_" prefix)
+ERROR: 0:142: '#define' : can't use with built-in names ("GL_" prefix)
+ERROR: 0:143: '#define' : can't use with built-in names (containing consecutive underscores)
+ERROR: 0:144: '#define' : can't use with built-in names (containing consecutive underscores)
+ERROR: 0:145: '#define' : can't use with built-in names (containing consecutive underscores)
ERROR: 0:148: '#else' : unexpected tokens following directive
ERROR: 0:149: '#else' : #elif after #else
ERROR: 0:155: '#else' : unexpected tokens following directive
@@ -41,8 +41,10 @@
ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7
ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8
ERROR: 0:196: '#define' : Macro redefined; different argument names: m9
-ERROR: 0:206: '' : missing #endif
-ERROR: 43 compilation errors. No code generated.
+ERROR: 0:204: '#undef' : can't use with built-in names (containing consecutive underscores)
+ERROR: 0:205: '#undef' : can't use with built-in names ("GL_" prefix)
+ERROR: 0:209: '' : missing #endif
+ERROR: 45 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:5 Sequence
diff --git a/Test/baseResults/lineContinuation100.vert.out b/Test/baseResults/lineContinuation100.vert.out
new file mode 100644
index 0000000..640dbee
--- /dev/null
+++ b/Test/baseResults/lineContinuation100.vert.out
@@ -0,0 +1,21 @@
+ERROR: 0:3: 'line continuation' : not supported for this version or the enabled extensions
+ERROR: 0:6: '#error' : e1
+ERROR: 0:8: 'line continuation' : not supported for this version or the enabled extensions
+ERROR: 0:11: '#error' : e2
+ERROR: 0:13: 'line continuation' : not supported for this version or the enabled extensions
+ERROR: 0:14: 'line continuation' : not supported for this version or the enabled extensions
+ERROR: 0:15: 'line continuation' : not supported for this version or the enabled extensions
+ERROR: 0:18: '#error' : e3
+ERROR: 8 compilation errors. No code generated.
+
+ERROR: node is still EOpNull!
+0:20 Function Definition: main( (void)
+0:20 Function Parameters:
+0:20 Sequence
+0:20 move second child to first child (highp 4-component vector of float)
+0:20 'gl_Position' (gl_Position highp 4-component vector of float)
+0:20 Construct vec4 (highp 4-component vector of float)
+0:20 'foo' (highp float)
+0:? Linker Objects
+0:? 'foo' (highp float)
+
diff --git a/Test/baseResults/versionsErrors.frag.out b/Test/baseResults/versionsErrors.frag.out
index b339567..cde4e28 100644
--- a/Test/baseResults/versionsErrors.frag.out
+++ b/Test/baseResults/versionsErrors.frag.out
@@ -2,7 +2,8 @@
ERROR: 0:38: 'attribute' : not supported in this stage: fragment
ERROR: 0:40: 'sampler2DRect' : Reserved word.
ERROR: 0:40: 'rectangle texture' : not supported for this version or the enabled extensions
-ERROR: 4 compilation errors. No code generated.
+ERROR: 0:44: 'floating-point suffix' : not supported for this version or the enabled extensions
+ERROR: 5 compilation errors. No code generated.
ERROR: node is still EOpNull!
0:42 Function Definition: main( (void)
diff --git a/Test/cppNest.vert b/Test/cppNest.vert
index 41c5a6a..a3dc5fa 100644
--- a/Test/cppNest.vert
+++ b/Test/cppNest.vert
@@ -85,3 +85,52 @@
// sum should be 987600301.0
gl_Position = vec4(sum);
}
+
+#define A 1
+#define C 0
+#define E 0
+#define F 1
+#if A
+ #if C
+ #if E
+ int selected4 = 1;
+ #elif F
+ int selected4 = 2;
+ #else
+ int selected4 = 3;
+ #endif
+ #endif
+ int selected4 = 4;
+#endif
+
+#define ZA 1
+#define ZC 1
+#define ZE 0
+#define ZF 1
+#if ZA
+ #if ZC
+ #if ZE
+ int selected2 = 1;
+ #elif ZF
+ int selected2 = 2;
+ #else
+ int selected2 = 3;
+ #endif
+ #endif
+#endif
+
+#define AZA 1
+#define AZC 1
+#define AZE 0
+#define AZF 0
+#if AZA
+ #if AZC
+ #if AZE
+ int selected3 = 1;
+ #elif AZF
+ int selected3 = 2;
+ #else
+ int selected3 = 3;
+ #endif
+ #endif
+#endif
diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert
index f200fbe..59854fd 100644
--- a/Test/cppSimple.vert
+++ b/Test/cppSimple.vert
@@ -201,6 +201,9 @@
#define f1 .08e-2Lf
double f = f1;
+#undef __VERSION__
+#undef GL_ARB_texture_rectangle
+
#if 1
#else
// ERROR, missing #endif
\ No newline at end of file
diff --git a/Test/lineContinuation100.vert b/Test/lineContinuation100.vert
new file mode 100644
index 0000000..0b0cc30
--- /dev/null
+++ b/Test/lineContinuation100.vert
@@ -0,0 +1,20 @@
+#version 100
+
+// this file cont\
+ains no errors other than the #error which are there to see if line numbering for errors is correct
+
+#error e1
+
+float f\
+oo; // same as 'float foo;'
+
+#error e2
+
+#define MAIN void main() \
+{ \
+gl_Position = vec4(foo); \
+}
+
+#error e3
+
+MAIN
diff --git a/Test/precision.frag b/Test/precision.frag
index 0531322..e24fa52 100644
--- a/Test/precision.frag
+++ b/Test/precision.frag
@@ -26,7 +26,7 @@
{
lowp int sum = global_medium + global_high;
- gl_FragColor = vec4(color, 1.0f);
+ gl_FragColor = vec4(color, 1.0);
int level1_high;
sum += level1_high;
diff --git a/Test/sample.frag b/Test/sample.frag
index 540b4a7..d9b9f5c 100644
--- a/Test/sample.frag
+++ b/Test/sample.frag
@@ -37,5 +37,5 @@
void main()
{
- gl_FragColor = vec4(color, 1.0f);
+ gl_FragColor = vec4(color, 1.0);
}
diff --git a/Test/testlist b/Test/testlist
index 74d5d84..f79b118 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -50,6 +50,7 @@
420.vert
420.geom
430scope.vert
+lineContinuation100.vert
lineContinuation.vert
numeral.frag
400.geom
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 12fb3eb..f23b37e 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -1370,6 +1370,35 @@
return false;
}
+//
+// Reserved errors for the preprocessor.
+//
+void TParseContext::reservedPpErrorCheck(TSourceLoc loc, const char* identifier, const char* op)
+{
+ // "All macro names containing two consecutive underscores ( __ ) are reserved for future use as predefined
+ // macro names. All macro names prefixed with "GL_" ("GL" followed by a single underscore) are also
+ // reserved."
+ if (strncmp(identifier, "GL_", 3) == 0)
+ error(loc, "can't use with built-in names (\"GL_\" prefix)", op, "");
+ else if (strstr(identifier, "__") != 0)
+ error(loc, "can't use with built-in names (containing consecutive underscores)", op, "");
+}
+
+//
+// See if this version/profile allows use of the line-continuation character '\'.
+//
+void TParseContext::lineContinuationCheck(TSourceLoc loc)
+{
+ const char* message = "line continuation";
+ if (messages & EShMsgRelaxedErrors) {
+ warn(loc, "not allowed in this version", message, "");
+ } else {
+ requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, message);
+ profileRequires(loc, EEsProfile, 300, 0, message);
+ profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 0, message);
+ }
+}
+
bool TParseContext::builtInName(const TString& identifier)
{
return identifier.compare(0, 3, "gl_") == 0;
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index c7680ba..81426be 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -75,6 +75,8 @@
void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...);
bool reservedErrorCheck(TSourceLoc, const TString&);
+ void reservedPpErrorCheck(TSourceLoc, const char* name, const char* op);
+ void lineContinuationCheck(TSourceLoc);
bool builtInName(const TString&);
void handlePragma(const char **tokens, int numTokens);
diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp
index dd2b68a..af62318 100644
--- a/glslang/MachineIndependent/preprocessor/Pp.cpp
+++ b/glslang/MachineIndependent/preprocessor/Pp.cpp
@@ -151,13 +151,7 @@
const char* definedName = GetAtomString(atom);
if (ppToken->loc.string >= 0) {
// We are in user code; check for reserved name use:
- // "All macro names containing two consecutive underscores ( __ ) are reserved for future use as predefined
- // macro names. All macro names prefixed with "GL_" ("GL" followed by a single underscore) are also
- // reserved."
- if (strncmp(definedName, "GL_", 3) == 0)
- parseContext.error(ppToken->loc, "reserved built-in name prefix:", "#define", "GL_");
- else if (strstr(definedName, "__") != 0)
- parseContext.error(ppToken->loc, "names containing consecutive underscores are reserved", "#define", "");
+ parseContext.reservedPpErrorCheck(ppToken->loc, definedName, "#define");
}
token = currentInput->scan(this, currentInput, ppToken);
if (token == '(' && !ppToken->ival) {
@@ -203,6 +197,7 @@
mac.body = NewTokenStream(pool);
while (token != '\n') {
if (token == '\\') {
+ parseContext.lineContinuationCheck(ppToken->loc);
token = currentInput->scan(this, currentInput, ppToken);
if (token == '\n')
token = currentInput->scan(this, currentInput, ppToken);
@@ -253,21 +248,19 @@
return '\n';
}
-int TPpContext::CPPundef(TPpToken * ppToken)
+int TPpContext::CPPundef(TPpToken* ppToken)
{
int token = currentInput->scan(this, currentInput, ppToken);
Symbol *symb;
- if (token == '\n') {
- parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
-
- return token;
- }
if (token != CPP_IDENTIFIER) {
parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
return token;
}
+ const char* name = GetAtomString(ppToken->atom); // TODO preprocessor simplification: the token text should have been built into the ppToken during currentInput->scan()
+ parseContext.reservedPpErrorCheck(ppToken->loc, name, "#undef");
+
symb = LookUpSymbol(ppToken->atom);
if (symb) {
symb->mac.undef = 1;
@@ -311,7 +304,7 @@
elsetracker++;
} else if (atom == endifAtom) {
token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
- elsedepth[elsetracker] = 0;
+ elseSeen[elsetracker] = false;
--elsetracker;
if (depth == 0) {
// found the #endif we are looking for
@@ -331,21 +324,21 @@
* it and we really want to leave it alone */
if (ifdepth) {
--ifdepth;
- elsedepth[elsetracker] = 0;
+ elseSeen[elsetracker] = false;
--elsetracker;
}
return CPPif(ppToken);
}
- } else if (atom == elseAtom || atom == elifAtom) {
- if (! ChkCorrectElseNesting()) {
- if (atom == elseAtom)
- parseContext.error(ppToken->loc, "#else after #else", "#else", "");
- else
- parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
- }
- if (atom == elseAtom)
- token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
+ } else if (atom == elseAtom) {
+ if (elseSeen[elsetracker])
+ parseContext.error(ppToken->loc, "#else after #else", "#else", "");
+ else
+ elseSeen[elsetracker] = true;
+ token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
+ } else if (atom == elifAtom) {
+ if (elseSeen[elsetracker])
+ parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
}
}
@@ -807,7 +800,8 @@
if (ppToken->atom == defineAtom) {
token = CPPdefine(ppToken);
} else if (ppToken->atom == elseAtom) {
- if (ChkCorrectElseNesting()) {
+ if (! elsetracker[elseSeen]) {
+ elsetracker[elseSeen] = true;
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
@@ -826,7 +820,7 @@
token = currentInput->scan(this, currentInput, ppToken);
token = CPPelse(0, ppToken);
} else if (ppToken->atom == endifAtom) {
- elsedepth[elsetracker] = 0;
+ elseSeen[elsetracker] = false;
--elsetracker;
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
@@ -1106,15 +1100,4 @@
return 1;
}
-int TPpContext::ChkCorrectElseNesting()
-{
- if (elsedepth[elsetracker] == 0) {
- elsedepth[elsetracker] = 1;
-
- return 1;
- }
-
- return 0;
-}
-
} // end namespace glslang
\ No newline at end of file
diff --git a/glslang/MachineIndependent/preprocessor/PpContext.cpp b/glslang/MachineIndependent/preprocessor/PpContext.cpp
index 29af6bb..21af119 100644
--- a/glslang/MachineIndependent/preprocessor/PpContext.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpContext.cpp
@@ -91,7 +91,7 @@
ifdepth = 0;
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
- elsedepth[elsetracker] = 0;
+ elseSeen[elsetracker] = false;
elsetracker = 0;
}
diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h
index 22b35be..5982ce0 100644
--- a/glslang/MachineIndependent/preprocessor/PpContext.h
+++ b/glslang/MachineIndependent/preprocessor/PpContext.h
@@ -196,9 +196,9 @@
static const int maxMacroArgs = 64;
static const int maxIfNesting = 64;
- int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
- int elsedepth[maxIfNesting]; // Keep a track of #if depth..Max allowed is 64.
- int elsetracker; // #if-#else and #endif constructs...Counter.
+ int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
+ bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
+ int elsetracker; // #if-#else and #endif constructs...Counter.
const char *ErrMsg;
struct MacroInputSrc {
@@ -262,7 +262,6 @@
static int macro_scan(TPpContext* pp, InputSrc *inInput, TPpToken * ppToken);
static int zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken * ppToken);
int MacroExpand(int atom, TPpToken* ppToken, int expandUndef);
- int ChkCorrectElseNesting();
//
// from PpSymbols.cpp
diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
index 57cc502..aed147c 100644
--- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
@@ -202,6 +202,7 @@
strcpy(str, "0.0");
} else {
if (ch == 'l' || ch == 'L') {
+ parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
if (! HasDecimalOrExponent)
parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
int ch2 = currentInput->getch(this, currentInput, ppToken);
@@ -219,6 +220,8 @@
}
}
} else if (ch == 'f' || ch == 'F') {
+ parseContext.profileRequires(ppToken->loc, EEsProfile, 300, 0, "floating-point suffix");
+ parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, 0, "floating-point suffix");
if (! HasDecimalOrExponent)
parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
if (len < TPpToken::maxTokenLength)
@@ -230,7 +233,7 @@
} else
currentInput->ungetch(this, currentInput, ch, ppToken);
- str[len]='\0';
+ str[len]='\0';
ppToken->dval = strtod(str, 0);
}
@@ -282,6 +285,7 @@
do {
if (ch == '\\') {
// escaped character
+ pp->parseContext.lineContinuationCheck(ppToken->loc);
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\r' || ch == '\n') {
int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
@@ -631,6 +635,7 @@
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\\') {
// allow an escaped newline, otherwise escapes in comments are meaningless
+ pp->parseContext.lineContinuationCheck(ppToken->loc);
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\r' || ch == '\n') {
int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
@@ -678,7 +683,8 @@
case '"':
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
while (ch != '"' && ch != '\n' && ch != EOF) {
- if (ch == '\\') {
+ if (ch == '\\') {
+ pp->parseContext.lineContinuationCheck(ppToken->loc);
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\n' || ch == EOF) {
break;