Improve robustness of extension checking, and its intersection with ES 100 features.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23388 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
c6b7e6350b
commit
816e9bc90b
45
Test/100.frag
Normal file
45
Test/100.frag
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
int a[3] = { 2, 3, 4, }; // ERROR
|
||||||
|
|
||||||
|
int uint;
|
||||||
|
|
||||||
|
attribute vec4 v[3]; // ERROR
|
||||||
|
|
||||||
|
float f = 2; // ERROR
|
||||||
|
|
||||||
|
uniform block { // ERROR
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
|
||||||
|
void foo(float);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
foo(3); // ERROR
|
||||||
|
int s = 1 << 4; // ERROR
|
||||||
|
s = 16 >> 2; // ERROR
|
||||||
|
if (a == a); // ERROR
|
||||||
|
int b, c;
|
||||||
|
b = c & 4; // ERROR
|
||||||
|
b = c % 4; // ERROR
|
||||||
|
b = c | 4; // ERROR
|
||||||
|
b >>= 2; // ERROR
|
||||||
|
b <<= 2; // ERROR
|
||||||
|
b %= 3; // ERROR
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
float f;
|
||||||
|
float a[10];
|
||||||
|
} s1, s2;
|
||||||
|
|
||||||
|
s1 = s2; // ERROR
|
||||||
|
if (s1 == s2); // ERROR
|
||||||
|
if (s1 != s2); // ERROR
|
||||||
|
|
||||||
|
switch(b) { // ERROR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
invariant gl_FragColor;
|
||||||
|
float fa[]; // ERROR
|
||||||
@ -21,7 +21,7 @@ void main()
|
|||||||
gu[2] = 4.0; // ERROR, overflow
|
gu[2] = 4.0; // ERROR, overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
g4 = foo(g5);
|
g4 = foo(g5); // ERROR
|
||||||
g5 = g4; // ERROR
|
g5 = g4; // ERROR
|
||||||
gu = g4; // ERROR
|
gu = g4; // ERROR
|
||||||
|
|
||||||
|
|||||||
100
Test/baseResults/100.frag.out
Normal file
100
Test/baseResults/100.frag.out
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
ERROR: 0:3: '{ } style initializers' : not supported with this profile: es
|
||||||
|
ERROR: 0:3: 'initializer' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:3: '=' : cannot convert from 'const int' to '3-element array of mediump int'
|
||||||
|
ERROR: 0:7: 'attribute' : not supported in this stage: fragment
|
||||||
|
ERROR: 0:7: 'float' : type requires declaration of default precision qualifier
|
||||||
|
ERROR: 0:9: '=' : cannot convert from 'const int' to 'mediump float'
|
||||||
|
ERROR: 0:11: 'uniform block' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:19: 'foo' : no matching overloaded function found
|
||||||
|
ERROR: 0:20: 'bit shift left' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:21: 'bit shift right' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:22: 'array comparison' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:24: 'bitwise and' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:25: '%' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:26: 'bitwise inclusive or' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:27: 'bit-shift right assign' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:28: 'bit-shift left assign' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:29: '%=' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:36: 'array assignment' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:37: 'array comparison' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:38: 'array comparison' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:40: 'switch' : Reserved word.
|
||||||
|
ERROR: 0:40: 'switch statements' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:45: '' : array size required
|
||||||
|
ERROR: 23 compilation errors. No code generated.
|
||||||
|
|
||||||
|
ERROR: node is still EOpNull!
|
||||||
|
0:17 Function Definition: main( (void)
|
||||||
|
0:17 Function Parameters:
|
||||||
|
0:19 Sequence
|
||||||
|
0:19 Constant:
|
||||||
|
0:19 0.000000
|
||||||
|
0:20 Sequence
|
||||||
|
0:20 move second child to first child (mediump int)
|
||||||
|
0:20 's' (mediump int)
|
||||||
|
0:20 Constant:
|
||||||
|
0:20 16 (const int)
|
||||||
|
0:21 move second child to first child (mediump int)
|
||||||
|
0:21 's' (mediump int)
|
||||||
|
0:21 Constant:
|
||||||
|
0:21 4 (const int)
|
||||||
|
0:22 Test condition and select (void)
|
||||||
|
0:22 Condition
|
||||||
|
0:22 Compare Equal (bool)
|
||||||
|
0:22 'a' (3-element array of mediump int)
|
||||||
|
0:22 'a' (3-element array of mediump int)
|
||||||
|
0:22 true case is null
|
||||||
|
0:24 move second child to first child (mediump int)
|
||||||
|
0:24 'b' (mediump int)
|
||||||
|
0:24 bitwise and (mediump int)
|
||||||
|
0:24 'c' (mediump int)
|
||||||
|
0:24 Constant:
|
||||||
|
0:24 4 (const int)
|
||||||
|
0:25 move second child to first child (mediump int)
|
||||||
|
0:25 'b' (mediump int)
|
||||||
|
0:25 mod (mediump int)
|
||||||
|
0:25 'c' (mediump int)
|
||||||
|
0:25 Constant:
|
||||||
|
0:25 4 (const int)
|
||||||
|
0:26 move second child to first child (mediump int)
|
||||||
|
0:26 'b' (mediump int)
|
||||||
|
0:26 inclusive-or (mediump int)
|
||||||
|
0:26 'c' (mediump int)
|
||||||
|
0:26 Constant:
|
||||||
|
0:26 4 (const int)
|
||||||
|
0:27 right shift second child into first child (mediump int)
|
||||||
|
0:27 'b' (mediump int)
|
||||||
|
0:27 Constant:
|
||||||
|
0:27 2 (const int)
|
||||||
|
0:28 left shift second child into first child (mediump int)
|
||||||
|
0:28 'b' (mediump int)
|
||||||
|
0:28 Constant:
|
||||||
|
0:28 2 (const int)
|
||||||
|
0:29 mod second child into first child (mediump int)
|
||||||
|
0:29 'b' (mediump int)
|
||||||
|
0:29 Constant:
|
||||||
|
0:29 3 (const int)
|
||||||
|
0:36 move second child to first child (structure)
|
||||||
|
0:36 's1' (structure)
|
||||||
|
0:36 's2' (structure)
|
||||||
|
0:37 Test condition and select (void)
|
||||||
|
0:37 Condition
|
||||||
|
0:37 Compare Equal (bool)
|
||||||
|
0:37 's1' (structure)
|
||||||
|
0:37 's2' (structure)
|
||||||
|
0:37 true case is null
|
||||||
|
0:38 Test condition and select (void)
|
||||||
|
0:38 Condition
|
||||||
|
0:38 Compare Not Equal (bool)
|
||||||
|
0:38 's1' (structure)
|
||||||
|
0:38 's2' (structure)
|
||||||
|
0:38 true case is null
|
||||||
|
0:40 'b' (mediump int)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'a' (3-element array of mediump int)
|
||||||
|
0:? 'uint' (mediump int)
|
||||||
|
0:? 'v' (smooth in 3-element array of mediump 4-component vector of float)
|
||||||
|
0:? 'f' (mediump float)
|
||||||
|
0:? '__anon__0' (layout(shared ) uniform block)
|
||||||
|
0:? 'fa' (unsized array of mediump float)
|
||||||
|
|
||||||
@ -4,14 +4,18 @@ ERROR: 0:9: 'arrayed type' : not supported for this version or the enabled exten
|
|||||||
ERROR: 0:9: 'arrayed type' : not supported for this version or the enabled extensions
|
ERROR: 0:9: 'arrayed type' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:11: 'arrayed constructor' : not supported for this version or the enabled extensions
|
ERROR: 0:11: 'arrayed constructor' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:21: '[' : array index out of range '2'
|
ERROR: 0:21: '[' : array index out of range '2'
|
||||||
|
ERROR: 0:24: 'array assignment' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:25: 'array assignment' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:25: 'assign' : cannot convert from '4-element array of mediump float' to '5-element array of mediump float'
|
ERROR: 0:25: 'assign' : cannot convert from '4-element array of mediump float' to '5-element array of mediump float'
|
||||||
|
ERROR: 0:26: 'array assignment' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:26: 'assign' : cannot convert from '4-element array of mediump float' to 'unsized array of mediump float'
|
ERROR: 0:26: 'assign' : cannot convert from '4-element array of mediump float' to 'unsized array of mediump float'
|
||||||
ERROR: 0:28: 'foo' : no matching overloaded function found
|
ERROR: 0:28: 'foo' : no matching overloaded function found
|
||||||
ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions
|
ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions
|
||||||
|
ERROR: 0:31: 'array comparison' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:35: '[' : array index out of range '5'
|
ERROR: 0:35: '[' : array index out of range '5'
|
||||||
ERROR: 0:38: '[' : array index out of range '1000'
|
ERROR: 0:38: '[' : array index out of range '1000'
|
||||||
ERROR: 0:39: '[' : array index out of range '-1'
|
ERROR: 0:39: '[' : array index out of range '-1'
|
||||||
ERROR: 13 compilation errors. No code generated.
|
ERROR: 17 compilation errors. No code generated.
|
||||||
|
|
||||||
ERROR: node is still EOpNull!
|
ERROR: node is still EOpNull!
|
||||||
0:9 Function Definition: foo(f1[5]; (4-element array of mediump float)
|
0:9 Function Definition: foo(f1[5]; (4-element array of mediump float)
|
||||||
@ -86,9 +90,9 @@ ERROR: node is still EOpNull!
|
|||||||
0:35 5.000000
|
0:35 5.000000
|
||||||
0:36 Function Call: foo(f1[5]; (4-element array of mediump float)
|
0:36 Function Call: foo(f1[5]; (4-element array of mediump float)
|
||||||
0:36 'u' (5-element array of mediump float)
|
0:36 'u' (5-element array of mediump float)
|
||||||
0:38 move second child to first child (4-component vector of float)
|
0:38 move second child to first child (mediump 4-component vector of float)
|
||||||
0:38 direct index (fragColor 4-component vector of float)
|
0:38 direct index (fragColor mediump 4-component vector of float)
|
||||||
0:38 'gl_FragData' (fragColor 32-element array of 4-component vector of float)
|
0:38 'gl_FragData' (fragColor 32-element array of mediump 4-component vector of float)
|
||||||
0:38 Constant:
|
0:38 Constant:
|
||||||
0:38 1000 (const int)
|
0:38 1000 (const int)
|
||||||
0:38 Constant:
|
0:38 Constant:
|
||||||
@ -96,9 +100,9 @@ ERROR: node is still EOpNull!
|
|||||||
0:38 1.000000
|
0:38 1.000000
|
||||||
0:38 1.000000
|
0:38 1.000000
|
||||||
0:38 1.000000
|
0:38 1.000000
|
||||||
0:39 move second child to first child (4-component vector of float)
|
0:39 move second child to first child (mediump 4-component vector of float)
|
||||||
0:39 direct index (fragColor 4-component vector of float)
|
0:39 direct index (fragColor mediump 4-component vector of float)
|
||||||
0:39 'gl_FragData' (fragColor 32-element array of 4-component vector of float)
|
0:39 'gl_FragData' (fragColor 32-element array of mediump 4-component vector of float)
|
||||||
0:39 Constant:
|
0:39 Constant:
|
||||||
0:39 -1 (const int)
|
0:39 -1 (const int)
|
||||||
0:39 Constant:
|
0:39 Constant:
|
||||||
@ -106,9 +110,9 @@ ERROR: node is still EOpNull!
|
|||||||
0:39 1.000000
|
0:39 1.000000
|
||||||
0:39 1.000000
|
0:39 1.000000
|
||||||
0:39 1.000000
|
0:39 1.000000
|
||||||
0:40 move second child to first child (4-component vector of float)
|
0:40 move second child to first child (mediump 4-component vector of float)
|
||||||
0:40 direct index (fragColor 4-component vector of float)
|
0:40 direct index (fragColor mediump 4-component vector of float)
|
||||||
0:40 'gl_FragData' (fragColor 32-element array of 4-component vector of float)
|
0:40 'gl_FragData' (fragColor 32-element array of mediump 4-component vector of float)
|
||||||
0:40 Constant:
|
0:40 Constant:
|
||||||
0:40 3 (const int)
|
0:40 3 (const int)
|
||||||
0:40 Constant:
|
0:40 Constant:
|
||||||
|
|||||||
@ -7,6 +7,7 @@ versionsClean.frag
|
|||||||
versionsClean.vert
|
versionsClean.vert
|
||||||
versionsErrors.frag
|
versionsErrors.frag
|
||||||
versionsErrors.vert
|
versionsErrors.vert
|
||||||
|
100.frag
|
||||||
120.vert
|
120.vert
|
||||||
120.frag
|
120.frag
|
||||||
130.frag
|
130.frag
|
||||||
|
|||||||
@ -580,6 +580,18 @@ public:
|
|||||||
|
|
||||||
virtual bool isMatrix() const { return matrixCols ? true : false; }
|
virtual bool isMatrix() const { return matrixCols ? true : false; }
|
||||||
virtual bool isArray() const { return arraySizes != 0; }
|
virtual bool isArray() const { return arraySizes != 0; }
|
||||||
|
virtual bool containsArray() const
|
||||||
|
{
|
||||||
|
if (isArray())
|
||||||
|
return true;
|
||||||
|
if (! structure)
|
||||||
|
return false;
|
||||||
|
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||||
|
if ((*structure)[i].type->containsArray())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int getArraySize() const { return arraySizes->sizes.front(); }
|
int getArraySize() const { return arraySizes->sizes.front(); }
|
||||||
void setArraySizes(TArraySizes* s)
|
void setArraySizes(TArraySizes* s)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -35,10 +35,16 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create strings that declare built-in definitions, add built-ins that
|
// Create strings that declare built-in definitions, add built-ins programmatically
|
||||||
// cannot be expressed in the files, and establish mappings between
|
// that cannot be expressed in the strings, and establish mappings between
|
||||||
// built-in functions and operators.
|
// built-in functions and operators.
|
||||||
//
|
//
|
||||||
|
// Where to put a built-in:
|
||||||
|
// TBuiltIns::initialize(version,profile) context-independent textual built-ins; add them to the right string
|
||||||
|
// TBuiltIns::initialize(resources,...) context-dependent textual built-ins; add them to the right string
|
||||||
|
// IdentifyBuiltIns(...,symbolTable) context-independent programmatic additions/mappings to the symbol table
|
||||||
|
// IdentifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the symbol table
|
||||||
|
//
|
||||||
|
|
||||||
#include "../Include/intermediate.h"
|
#include "../Include/intermediate.h"
|
||||||
#include "Initialize.h"
|
#include "Initialize.h"
|
||||||
@ -50,14 +56,16 @@ const bool ForwardCompatibility = false;
|
|||||||
|
|
||||||
TBuiltIns::TBuiltIns()
|
TBuiltIns::TBuiltIns()
|
||||||
{
|
{
|
||||||
|
// Set up textual representations for making all the permutations
|
||||||
|
// of texturing/imaging functions.
|
||||||
prefixes[EbtFloat] = "";
|
prefixes[EbtFloat] = "";
|
||||||
prefixes[EbtInt] = "i";
|
prefixes[EbtInt] = "i";
|
||||||
prefixes[EbtUint] = "u";
|
prefixes[EbtUint] = "u";
|
||||||
|
|
||||||
postfixes[2] = "2";
|
postfixes[2] = "2";
|
||||||
postfixes[3] = "3";
|
postfixes[3] = "3";
|
||||||
postfixes[4] = "4";
|
postfixes[4] = "4";
|
||||||
|
|
||||||
|
// Map from symbolic class of texturing dimension to numeric dimensions.
|
||||||
dimMap[Esd1D] = 1;
|
dimMap[Esd1D] = 1;
|
||||||
dimMap[Esd2D] = 2;
|
dimMap[Esd2D] = 2;
|
||||||
dimMap[EsdRect] = 2;
|
dimMap[EsdRect] = 2;
|
||||||
@ -70,14 +78,16 @@ TBuiltIns::~TBuiltIns()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add all context-independent built-in functions and variables that are present
|
||||||
|
// for the given version and profile. Share common ones across stages, otherwise
|
||||||
|
// make stage-specific entries.
|
||||||
|
//
|
||||||
|
// Most built-ins variables can be added as simple text strings. Some need to
|
||||||
|
// be added programmatically, which is done later in IdentifyBuiltIns() below.
|
||||||
|
//
|
||||||
void TBuiltIns::initialize(int version, EProfile profile)
|
void TBuiltIns::initialize(int version, EProfile profile)
|
||||||
{
|
{
|
||||||
// TODO: Performance/Memory: consider an extra outer scope for built-ins common across all stages
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize all the built-in strings for parsing.
|
|
||||||
//
|
|
||||||
|
|
||||||
{
|
{
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
@ -1011,6 +1021,10 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||||||
//printf("%s\n", commonBuiltins.c_str();
|
//printf("%s\n", commonBuiltins.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper function for initialize(), to add the second set of names for texturing,
|
||||||
|
// when adding context-independent built-in functions.
|
||||||
|
//
|
||||||
void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile)
|
void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile)
|
||||||
{
|
{
|
||||||
TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint };
|
TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint };
|
||||||
@ -1081,6 +1095,10 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper function for add2ndGenerationSamplingImaging(),
|
||||||
|
// when adding context-independent built-in functions.
|
||||||
|
//
|
||||||
void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -1109,15 +1127,21 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int versi
|
|||||||
s.append(",int);\n");
|
s.append(",int);\n");
|
||||||
else
|
else
|
||||||
s.append(");\n");
|
s.append(");\n");
|
||||||
|
|
||||||
// TODO: 4.2 Functionality: imaging functions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper function for add2ndGenerationSamplingImaging(),
|
||||||
|
// when adding context-independent built-in functions.
|
||||||
|
//
|
||||||
void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
// TODO: 4.2 Functionality: imaging functions
|
// TODO: 4.2 Functionality: imaging functions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper function for add2ndGenerationSamplingImaging(),
|
||||||
|
// when adding context-independent built-in functions.
|
||||||
|
//
|
||||||
void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
|
||||||
{
|
{
|
||||||
// make one string per stage to contain all functions of the passed-in type for that stage
|
// make one string per stage to contain all functions of the passed-in type for that stage
|
||||||
@ -1297,6 +1321,11 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int ve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add context-dependent built-in functions and variables that are present
|
||||||
|
// for the given version and profile. Share common ones across stages, otherwise
|
||||||
|
// make stage-specific entries.
|
||||||
|
//
|
||||||
void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, EShLanguage language)
|
void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, EShLanguage language)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -1448,6 +1477,12 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Finish adding/processing context-independent built-in symbols.
|
||||||
|
// 1) Programmatically add symbols that could not be added by simple text strings above.
|
||||||
|
// 2) Map built-in functions to operators, for those that will turn into an operation node
|
||||||
|
// instead of remaining a function call.
|
||||||
|
//
|
||||||
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable)
|
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable)
|
||||||
{
|
{
|
||||||
TPrecisionQualifier pq;
|
TPrecisionQualifier pq;
|
||||||
@ -1643,11 +1678,13 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add context-dependent (resource-specific) built-ins not yet handled. These
|
||||||
|
// would be ones that need to be programmatically added because they cannot
|
||||||
|
// be added by simple text strings.
|
||||||
|
//
|
||||||
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
|
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Set resource-specific built-ins not yet handled.
|
|
||||||
//
|
|
||||||
switch(language) {
|
switch(language) {
|
||||||
|
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
|
|||||||
@ -45,6 +45,15 @@
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is made to hold parseable strings for almost all the built-in
|
||||||
|
// functions and variables for one specific combination of version
|
||||||
|
// and profile. (Some still need to be added programmatically.)
|
||||||
|
//
|
||||||
|
// The strings are organized by
|
||||||
|
// commonBuiltins: intersection of all stages' built-ins, processed just once
|
||||||
|
// stageBuiltins[]: anything a stage needs that's not in commonBuiltins
|
||||||
|
//
|
||||||
class TBuiltIns {
|
class TBuiltIns {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
@ -64,7 +73,8 @@ protected:
|
|||||||
TString commonBuiltins;
|
TString commonBuiltins;
|
||||||
TString stageBuiltins[EShLangCount];
|
TString stageBuiltins[EShLangCount];
|
||||||
|
|
||||||
// Helpers for making text
|
// Helpers for making textual representations of the permutations
|
||||||
|
// of texturing/imaging functions.
|
||||||
const char* postfixes[5];
|
const char* postfixes[5];
|
||||||
const char* prefixes[EbtNumTypes];
|
const char* prefixes[EbtNumTypes];
|
||||||
int dimMap[EsdNumDims];
|
int dimMap[EsdNumDims];
|
||||||
|
|||||||
@ -527,7 +527,8 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
|
|||||||
//
|
//
|
||||||
|
|
||||||
if (field == "length") {
|
if (field == "length") {
|
||||||
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", ".length");
|
profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, ".length");
|
||||||
|
profileRequires(loc, EEsProfile, 300, 0, ".length");
|
||||||
result = intermediate.addMethod(base, TType(EbtInt), &field, loc);
|
result = intermediate.addMethod(base, TType(EbtInt), &field, loc);
|
||||||
} else
|
} else
|
||||||
error(loc, "only the length method is supported for array", field.c_str(), "");
|
error(loc, "only the length method is supported for array", field.c_str(), "");
|
||||||
@ -851,8 +852,8 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
|
|||||||
TFunction* TParseContext::handleConstructorCall(TSourceLoc loc, TPublicType& publicType)
|
TFunction* TParseContext::handleConstructorCall(TSourceLoc loc, TPublicType& publicType)
|
||||||
{
|
{
|
||||||
if (publicType.arraySizes) {
|
if (publicType.arraySizes) {
|
||||||
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor");
|
profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed constructor");
|
||||||
profileRequires(loc, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor");
|
profileRequires(loc, EEsProfile, 300, 0, "arrayed constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
publicType.qualifier.precision = EpqNone;
|
publicType.qualifier.precision = EpqNone;
|
||||||
@ -1648,8 +1649,10 @@ void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size
|
|||||||
//
|
//
|
||||||
bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualifier)
|
bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualifier)
|
||||||
{
|
{
|
||||||
if (qualifier.storage == EvqConst)
|
if (qualifier.storage == EvqConst) {
|
||||||
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array");
|
profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "const array");
|
||||||
|
profileRequires(loc, EEsProfile, 300, 0, "const array");
|
||||||
|
}
|
||||||
|
|
||||||
if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
|
if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
|
||||||
requireProfile(loc, ~EEsProfile, "vertex input arrays");
|
requireProfile(loc, ~EEsProfile, "vertex input arrays");
|
||||||
@ -1893,6 +1896,15 @@ void TParseContext::nestedStructCheck(TSourceLoc loc)
|
|||||||
++structNestingLevel;
|
++structNestingLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseContext::arrayObjectCheck(TSourceLoc loc, const TType& type, const char* op)
|
||||||
|
{
|
||||||
|
// Some versions don't allow comparing arrays or structures containing arrays
|
||||||
|
if (type.containsArray()) {
|
||||||
|
profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, op);
|
||||||
|
profileRequires(loc, EEsProfile, 300, 0, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Layout qualifier stuff.
|
// Layout qualifier stuff.
|
||||||
//
|
//
|
||||||
@ -2020,8 +2032,10 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
|||||||
declareArray(loc, identifier, type, variable, newDeclaration);
|
declareArray(loc, identifier, type, variable, newDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initializer)
|
if (initializer) {
|
||||||
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
|
profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "initializer");
|
||||||
|
profileRequires(loc, EEsProfile, 300, 0, "initializer");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// non-array case
|
// non-array case
|
||||||
if (! variable)
|
if (! variable)
|
||||||
|
|||||||
@ -115,6 +115,7 @@ public:
|
|||||||
void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type);
|
void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type);
|
||||||
void nestedBlockCheck(TSourceLoc);
|
void nestedBlockCheck(TSourceLoc);
|
||||||
void nestedStructCheck(TSourceLoc);
|
void nestedStructCheck(TSourceLoc);
|
||||||
|
void arrayObjectCheck(TSourceLoc, const TType&, const char* op);
|
||||||
|
|
||||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
|
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
|
||||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
|
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
|
||||||
@ -161,7 +162,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char* getPreamble();
|
const char* getPreamble();
|
||||||
TExtensionBehavior getExtensionBehavior(const char* behavior);
|
|
||||||
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
|
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
|
||||||
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
|
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
|
||||||
void declareArray(TSourceLoc, TString& identifier, const TType&, TVariable*&, bool& newDeclaration);
|
void declareArray(TSourceLoc, TString& identifier, const TType&, TVariable*&, bool& newDeclaration);
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
// To add a new hypothetical "Feature F" to the front end, where an extension
|
// To add a new hypothetical "Feature F" to the front end, where an extension
|
||||||
// "XXX_extension_X" can be used to enable the feature, do the following.
|
// "XXX_extension_X" can be used to enable the feature, do the following.
|
||||||
//
|
//
|
||||||
// 1) Understand that specific features are what are error-checked for, not
|
// OVERVIEW: Specific features are what are error-checked for, not
|
||||||
// extensions: A specific Feature F might be enabled by an extension, or a
|
// extensions: A specific Feature F might be enabled by an extension, or a
|
||||||
// particular version in a particular profile, or a stage, or combinations, etc.
|
// particular version in a particular profile, or a stage, or combinations, etc.
|
||||||
//
|
//
|
||||||
@ -66,11 +66,17 @@
|
|||||||
// will then always continue as if the tested feature was enabled.
|
// will then always continue as if the tested feature was enabled.
|
||||||
//
|
//
|
||||||
// There is typically no if-testing or conditional parsing, just insertion of requirements.
|
// There is typically no if-testing or conditional parsing, just insertion of requirements.
|
||||||
|
// However, if symbols specific to the extension are added (step 5), they will
|
||||||
|
// only be added under tests that the minimum version and profile are present.
|
||||||
|
//
|
||||||
|
// 1) Add a symbol name for the extension string at the bottom of Versions.h:
|
||||||
|
//
|
||||||
|
// const char* const XXX_extension_X = "XXX_extension_X";
|
||||||
//
|
//
|
||||||
// 2) Add extension initialization to TParseContext::initializeExtensionBehavior(),
|
// 2) Add extension initialization to TParseContext::initializeExtensionBehavior(),
|
||||||
// the first function below:
|
// the first function below:
|
||||||
//
|
//
|
||||||
// extensionBehavior["XXX_extension_X"] = EBhDisable;
|
// extensionBehavior[XXX_extension_X] = EBhDisable;
|
||||||
//
|
//
|
||||||
// 3) Insert a profile check in the feature's path (unless all profiles support the feature,
|
// 3) Insert a profile check in the feature's path (unless all profiles support the feature,
|
||||||
// for some version level). That is, call requireProfile() to constrain the profiles, e.g.:
|
// for some version level). That is, call requireProfile() to constrain the profiles, e.g.:
|
||||||
@ -90,7 +96,7 @@
|
|||||||
// profileRequires(loc,
|
// profileRequires(loc,
|
||||||
// ECoreProfile | ECompatibilityProfile,
|
// ECoreProfile | ECompatibilityProfile,
|
||||||
// 420, // 0 if no version incorporated the feature into the core spec.
|
// 420, // 0 if no version incorporated the feature into the core spec.
|
||||||
// "XXX_extension_X", // can be a list of extensions that all add the feature
|
// XXX_extension_X, // can be a list of extensions that all add the feature
|
||||||
// "Feature F");
|
// "Feature F");
|
||||||
//
|
//
|
||||||
// This allows the feature if either A) one of the extensions is enabled or
|
// This allows the feature if either A) one of the extensions is enabled or
|
||||||
@ -117,6 +123,9 @@
|
|||||||
//
|
//
|
||||||
// ~EEsProfile
|
// ~EEsProfile
|
||||||
//
|
//
|
||||||
|
// 5) If built-in symbols are added by the extension, add them in Initialize.cpp; see
|
||||||
|
// the comment at the top of that file for where to put them.
|
||||||
|
//
|
||||||
|
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
|
||||||
@ -129,10 +138,14 @@ namespace glslang {
|
|||||||
//
|
//
|
||||||
void TParseContext::initializeExtensionBehavior()
|
void TParseContext::initializeExtensionBehavior()
|
||||||
{
|
{
|
||||||
extensionBehavior["GL_ARB_texture_rectangle"] = EBhDisable;
|
extensionBehavior[GL_ARB_texture_rectangle] = EBhDisable;
|
||||||
extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
|
extensionBehavior[GL_3DL_array_objects] = EBhDisable;
|
||||||
|
extensionBehavior[GL_ARB_shading_language_420pack] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Map from profile enum to externally readable text name.
|
||||||
|
//
|
||||||
const char* ProfileName(EProfile profile)
|
const char* ProfileName(EProfile profile)
|
||||||
{
|
{
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
@ -159,6 +172,9 @@ void TParseContext::requireProfile(TSourceLoc loc, int profileMask, const char *
|
|||||||
error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
|
error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Map from stage enum to externally readable text name.
|
||||||
|
//
|
||||||
const char* StageName(EShLanguage stage)
|
const char* StageName(EShLanguage stage)
|
||||||
{
|
{
|
||||||
switch(stage) {
|
switch(stage) {
|
||||||
@ -274,32 +290,27 @@ void TParseContext::requireNotRemoved(TSourceLoc loc, int profileMask, int remov
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Translate from text string of extension's behavior to enum.
|
// Change the current state of an extension's behavior.
|
||||||
//
|
//
|
||||||
TExtensionBehavior TParseContext::getExtensionBehavior(const char* behavior)
|
|
||||||
{
|
|
||||||
if (! strcmp("require", behavior))
|
|
||||||
return EBhRequire;
|
|
||||||
else if (! strcmp("enable", behavior))
|
|
||||||
return EBhEnable;
|
|
||||||
else if (! strcmp("disable", behavior))
|
|
||||||
return EBhDisable;
|
|
||||||
else if (! strcmp("warn", behavior))
|
|
||||||
return EBhWarn;
|
|
||||||
else {
|
|
||||||
error(currentLoc, "behavior not supported", "#extension", behavior);
|
|
||||||
return EBhDisable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TParseContext::updateExtensionBehavior(const char* extName, const char* behaviorString)
|
void TParseContext::updateExtensionBehavior(const char* extName, const char* behaviorString)
|
||||||
{
|
{
|
||||||
TExtensionBehavior behavior = getExtensionBehavior(behaviorString);
|
// Translate from text string of extension's behavior to an enum.
|
||||||
TMap<TString, TExtensionBehavior>:: iterator iter;
|
TExtensionBehavior behavior = EBhDisable;
|
||||||
TString msg;
|
if (! strcmp("require", behaviorString))
|
||||||
|
behavior = EBhRequire;
|
||||||
|
else if (! strcmp("enable", behaviorString))
|
||||||
|
behavior = EBhEnable;
|
||||||
|
else if (! strcmp("disable", behaviorString))
|
||||||
|
behavior = EBhDisable;
|
||||||
|
else if (! strcmp("warn", behaviorString))
|
||||||
|
behavior = EBhWarn;
|
||||||
|
else
|
||||||
|
error(currentLoc, "behavior not supported", "#extension", behaviorString);
|
||||||
|
|
||||||
// special case for the 'all' extension
|
// Update the current behavior
|
||||||
|
TMap<TString, TExtensionBehavior>::iterator iter;
|
||||||
if (! strcmp(extName, "all")) {
|
if (! strcmp(extName, "all")) {
|
||||||
|
// special case for the 'all' extension; apply it to every extension present
|
||||||
if (behavior == EBhRequire || behavior == EBhEnable) {
|
if (behavior == EBhRequire || behavior == EBhEnable) {
|
||||||
error(currentLoc, "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
|
error(currentLoc, "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
|
||||||
return;
|
return;
|
||||||
@ -308,6 +319,7 @@ void TParseContext::updateExtensionBehavior(const char* extName, const char* beh
|
|||||||
iter->second = behavior;
|
iter->second = behavior;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Do the update for this single extension
|
||||||
iter = extensionBehavior.find(TString(extName));
|
iter = extensionBehavior.find(TString(extName));
|
||||||
if (iter == extensionBehavior.end()) {
|
if (iter == extensionBehavior.end()) {
|
||||||
switch (behavior) {
|
switch (behavior) {
|
||||||
|
|||||||
@ -40,16 +40,6 @@
|
|||||||
// Help manage multiple profiles, versions, extensions etc.
|
// Help manage multiple profiles, versions, extensions etc.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
|
||||||
// The behaviors from "#extension extension_name : behavior"
|
|
||||||
//
|
|
||||||
typedef enum {
|
|
||||||
EBhRequire,
|
|
||||||
EBhEnable,
|
|
||||||
EBhWarn,
|
|
||||||
EBhDisable
|
|
||||||
} TExtensionBehavior;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Profiles are set up for masking operations, so queries can be done on multiple
|
// Profiles are set up for masking operations, so queries can be done on multiple
|
||||||
// profiles at the same time.
|
// profiles at the same time.
|
||||||
@ -65,4 +55,26 @@ typedef enum {
|
|||||||
EEsProfile = (1 << 3)
|
EEsProfile = (1 << 3)
|
||||||
} EProfile;
|
} EProfile;
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
//
|
||||||
|
// The behaviors from the GLSL "#extension extension_name : behavior"
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
EBhRequire,
|
||||||
|
EBhEnable,
|
||||||
|
EBhWarn,
|
||||||
|
EBhDisable
|
||||||
|
} TExtensionBehavior;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbolic names for extensions. Strings may be directly used when calling the
|
||||||
|
// functions, but better to have the compiler do spelling checks.
|
||||||
|
//
|
||||||
|
const char* const GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle";
|
||||||
|
const char* const GL_3DL_array_objects = "GL_3DL_array_objects";
|
||||||
|
const char* const GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack";
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _VERSIONS_INCLUDED_
|
#endif // _VERSIONS_INCLUDED_
|
||||||
|
|||||||
@ -463,6 +463,7 @@ multiplicative_expression
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
| multiplicative_expression PERCENT unary_expression {
|
| multiplicative_expression PERCENT unary_expression {
|
||||||
|
parseContext.fullIntegerCheck($2.loc, "%");
|
||||||
$$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc);
|
$$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc);
|
||||||
if ($$ == 0) {
|
if ($$ == 0) {
|
||||||
parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString());
|
parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString());
|
||||||
@ -552,24 +553,24 @@ relational_expression
|
|||||||
equality_expression
|
equality_expression
|
||||||
: relational_expression { $$ = $1; }
|
: relational_expression { $$ = $1; }
|
||||||
| equality_expression EQ_OP relational_expression {
|
| equality_expression EQ_OP relational_expression {
|
||||||
|
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");
|
||||||
$$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc);
|
$$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc);
|
||||||
if ($$ == 0) {
|
if ($$ == 0) {
|
||||||
parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString());
|
parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString());
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setBConst(false);
|
unionArray[0].setBConst(false);
|
||||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);
|
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);
|
||||||
} else if (($1->isArray() || $3->isArray()))
|
}
|
||||||
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "==");
|
|
||||||
}
|
}
|
||||||
| equality_expression NE_OP relational_expression {
|
| equality_expression NE_OP relational_expression {
|
||||||
|
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");
|
||||||
$$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc);
|
$$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc);
|
||||||
if ($$ == 0) {
|
if ($$ == 0) {
|
||||||
parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString());
|
parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString());
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setBConst(false);
|
unionArray[0].setBConst(false);
|
||||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);
|
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);
|
||||||
} else if (($1->isArray() || $3->isArray()))
|
}
|
||||||
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "!=");
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -664,23 +665,42 @@ conditional_expression
|
|||||||
assignment_expression
|
assignment_expression
|
||||||
: conditional_expression { $$ = $1; }
|
: conditional_expression { $$ = $1; }
|
||||||
| unary_expression assignment_operator assignment_expression {
|
| unary_expression assignment_operator assignment_expression {
|
||||||
|
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment");
|
||||||
parseContext.lValueErrorCheck($2.loc, "assign", $1);
|
parseContext.lValueErrorCheck($2.loc, "assign", $1);
|
||||||
$$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc);
|
$$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc);
|
||||||
if ($$ == 0) {
|
if ($$ == 0) {
|
||||||
parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
|
parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
} else if (($1->isArray() || $3->isArray()))
|
}
|
||||||
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "=");
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
assignment_operator
|
assignment_operator
|
||||||
: EQUAL { $$.loc = $1.loc; $$.op = EOpAssign; }
|
: EQUAL {
|
||||||
| MUL_ASSIGN { $$.loc = $1.loc; $$.op = EOpMulAssign; }
|
$$.loc = $1.loc;
|
||||||
| DIV_ASSIGN { $$.loc = $1.loc; $$.op = EOpDivAssign; }
|
$$.op = EOpAssign;
|
||||||
| MOD_ASSIGN { $$.loc = $1.loc; $$.op = EOpModAssign; }
|
}
|
||||||
| ADD_ASSIGN { $$.loc = $1.loc; $$.op = EOpAddAssign; }
|
| MUL_ASSIGN {
|
||||||
| SUB_ASSIGN { $$.loc = $1.loc; $$.op = EOpSubAssign; }
|
$$.loc = $1.loc;
|
||||||
|
$$.op = EOpMulAssign;
|
||||||
|
}
|
||||||
|
| DIV_ASSIGN {
|
||||||
|
$$.loc = $1.loc;
|
||||||
|
$$.op = EOpDivAssign;
|
||||||
|
}
|
||||||
|
| MOD_ASSIGN {
|
||||||
|
parseContext.fullIntegerCheck($1.loc, "%=");
|
||||||
|
$$.loc = $1.loc;
|
||||||
|
$$.op = EOpModAssign;
|
||||||
|
}
|
||||||
|
| ADD_ASSIGN {
|
||||||
|
$$.loc = $1.loc;
|
||||||
|
$$.op = EOpAddAssign;
|
||||||
|
}
|
||||||
|
| SUB_ASSIGN {
|
||||||
|
$$.loc = $1.loc;
|
||||||
|
$$.op = EOpSubAssign;
|
||||||
|
}
|
||||||
| LEFT_ASSIGN {
|
| LEFT_ASSIGN {
|
||||||
parseContext.fullIntegerCheck($1.loc, "bit-shift left assign");
|
parseContext.fullIntegerCheck($1.loc, "bit-shift left assign");
|
||||||
$$.loc = $1.loc; $$.op = EOpLeftShiftAssign;
|
$$.loc = $1.loc; $$.op = EOpLeftShiftAssign;
|
||||||
@ -853,7 +873,7 @@ parameter_declarator
|
|||||||
// Type + name
|
// Type + name
|
||||||
: type_specifier IDENTIFIER {
|
: type_specifier IDENTIFIER {
|
||||||
if ($1.arraySizes) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
||||||
}
|
}
|
||||||
@ -868,7 +888,7 @@ parameter_declarator
|
|||||||
}
|
}
|
||||||
| type_specifier IDENTIFIER array_specifier {
|
| type_specifier IDENTIFIER array_specifier {
|
||||||
if ($1.arraySizes) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
||||||
}
|
}
|
||||||
@ -989,7 +1009,7 @@ fully_specified_type
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
|
||||||
if ($1.arraySizes) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
||||||
@ -1001,7 +1021,7 @@ fully_specified_type
|
|||||||
parseContext.globalQualifierFix($1.loc, $1.qualifier, $2);
|
parseContext.globalQualifierFix($1.loc, $1.qualifier, $2);
|
||||||
|
|
||||||
if ($2.arraySizes) {
|
if ($2.arraySizes) {
|
||||||
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($2.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||||
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
|
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
|
||||||
@ -1676,28 +1696,28 @@ type_specifier_nonarray
|
|||||||
$$.sampler.set(EbtUint, EsdCube, true);
|
$$.sampler.set(EbtUint, EsdCube, true);
|
||||||
}
|
}
|
||||||
| SAMPLER2DRECT {
|
| SAMPLER2DRECT {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
|
parseContext.profileRequires($1.loc, ENoProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");
|
||||||
|
|
||||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
$$.basicType = EbtSampler;
|
$$.basicType = EbtSampler;
|
||||||
$$.sampler.set(EbtFloat, EsdRect);
|
$$.sampler.set(EbtFloat, EsdRect);
|
||||||
}
|
}
|
||||||
| SAMPLER2DRECTSHADOW {
|
| SAMPLER2DRECTSHADOW {
|
||||||
parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
|
parseContext.profileRequires($1.loc, ECoreProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");
|
||||||
|
|
||||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
$$.basicType = EbtSampler;
|
$$.basicType = EbtSampler;
|
||||||
$$.sampler.set(EbtFloat, EsdRect, false, true);
|
$$.sampler.set(EbtFloat, EsdRect, false, true);
|
||||||
}
|
}
|
||||||
| ISAMPLER2DRECT {
|
| ISAMPLER2DRECT {
|
||||||
parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
|
parseContext.profileRequires($1.loc, ECoreProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");
|
||||||
|
|
||||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
$$.basicType = EbtSampler;
|
$$.basicType = EbtSampler;
|
||||||
$$.sampler.set(EbtInt, EsdRect);
|
$$.sampler.set(EbtInt, EsdRect);
|
||||||
}
|
}
|
||||||
| USAMPLER2DRECT {
|
| USAMPLER2DRECT {
|
||||||
parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
|
parseContext.profileRequires($1.loc, ECoreProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");
|
||||||
|
|
||||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||||
$$.basicType = EbtSampler;
|
$$.basicType = EbtSampler;
|
||||||
@ -1992,7 +2012,7 @@ struct_declaration_list
|
|||||||
struct_declaration
|
struct_declaration
|
||||||
: type_specifier struct_declarator_list SEMICOLON {
|
: type_specifier struct_declarator_list SEMICOLON {
|
||||||
if ($1.arraySizes) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());
|
||||||
@ -2010,7 +2030,7 @@ struct_declaration
|
|||||||
}
|
}
|
||||||
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
|
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
|
||||||
if ($2.arraySizes) {
|
if ($2.arraySizes) {
|
||||||
parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($2.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||||
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
|
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
|
||||||
@ -2062,9 +2082,15 @@ initializer
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| LEFT_BRACE initializer_list RIGHT_BRACE {
|
| LEFT_BRACE initializer_list RIGHT_BRACE {
|
||||||
|
const char* initFeature = "{ } style initializers";
|
||||||
|
parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, initFeature);
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shading_language_420pack, initFeature);
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
|
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
|
||||||
|
const char* initFeature = "{ } style initializers";
|
||||||
|
parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, initFeature);
|
||||||
|
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shading_language_420pack, initFeature);
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user