--- /dev/null
+#version 100\r
+\r
+int a[3] = { 2, 3, 4, }; // ERROR\r
+\r
+int uint;\r
+\r
+attribute vec4 v[3]; // ERROR\r
+\r
+float f = 2; // ERROR\r
+\r
+uniform block { // ERROR\r
+ int x;\r
+};\r
+\r
+void foo(float);\r
+\r
+void main()\r
+{\r
+ foo(3); // ERROR\r
+ int s = 1 << 4; // ERROR\r
+ s = 16 >> 2; // ERROR\r
+ if (a == a); // ERROR\r
+ int b, c;\r
+ b = c & 4; // ERROR\r
+ b = c % 4; // ERROR\r
+ b = c | 4; // ERROR\r
+ b >>= 2; // ERROR\r
+ b <<= 2; // ERROR\r
+ b %= 3; // ERROR\r
+\r
+ struct S {\r
+ float f;\r
+ float a[10];\r
+ } s1, s2;\r
+\r
+ s1 = s2; // ERROR\r
+ if (s1 == s2); // ERROR\r
+ if (s1 != s2); // ERROR\r
+\r
+ switch(b) { // ERROR\r
+ }\r
+}\r
+\r
+invariant gl_FragColor;\r
+float fa[]; // ERROR\r
gu[2] = 4.0; // ERROR, overflow
}
- g4 = foo(g5);
+ g4 = foo(g5); // ERROR
g5 = g4; // ERROR
gu = g4; // ERROR
--- /dev/null
+ERROR: 0:3: '{ } style initializers' : not supported with this profile: es\r
+ERROR: 0:3: 'initializer' : not supported for this version or the enabled extensions \r
+ERROR: 0:3: '=' : cannot convert from 'const int' to '3-element array of mediump int'\r
+ERROR: 0:7: 'attribute' : not supported in this stage: fragment\r
+ERROR: 0:7: 'float' : type requires declaration of default precision qualifier \r
+ERROR: 0:9: '=' : cannot convert from 'const int' to 'mediump float'\r
+ERROR: 0:11: 'uniform block' : not supported for this version or the enabled extensions \r
+ERROR: 0:19: 'foo' : no matching overloaded function found \r
+ERROR: 0:20: 'bit shift left' : not supported for this version or the enabled extensions \r
+ERROR: 0:21: 'bit shift right' : not supported for this version or the enabled extensions \r
+ERROR: 0:22: 'array comparison' : not supported for this version or the enabled extensions \r
+ERROR: 0:24: 'bitwise and' : not supported for this version or the enabled extensions \r
+ERROR: 0:25: '%' : not supported for this version or the enabled extensions \r
+ERROR: 0:26: 'bitwise inclusive or' : not supported for this version or the enabled extensions \r
+ERROR: 0:27: 'bit-shift right assign' : not supported for this version or the enabled extensions \r
+ERROR: 0:28: 'bit-shift left assign' : not supported for this version or the enabled extensions \r
+ERROR: 0:29: '%=' : not supported for this version or the enabled extensions \r
+ERROR: 0:36: 'array assignment' : not supported for this version or the enabled extensions \r
+ERROR: 0:37: 'array comparison' : not supported for this version or the enabled extensions \r
+ERROR: 0:38: 'array comparison' : not supported for this version or the enabled extensions \r
+ERROR: 0:40: 'switch' : Reserved word. \r
+ERROR: 0:40: 'switch statements' : not supported for this version or the enabled extensions \r
+ERROR: 0:45: '' : array size required \r
+ERROR: 23 compilation errors. No code generated.\r
+\r
+ERROR: node is still EOpNull!\r
+0:17 Function Definition: main( (void)\r
+0:17 Function Parameters: \r
+0:19 Sequence\r
+0:19 Constant:\r
+0:19 0.000000\r
+0:20 Sequence\r
+0:20 move second child to first child (mediump int)\r
+0:20 's' (mediump int)\r
+0:20 Constant:\r
+0:20 16 (const int)\r
+0:21 move second child to first child (mediump int)\r
+0:21 's' (mediump int)\r
+0:21 Constant:\r
+0:21 4 (const int)\r
+0:22 Test condition and select (void)\r
+0:22 Condition\r
+0:22 Compare Equal (bool)\r
+0:22 'a' (3-element array of mediump int)\r
+0:22 'a' (3-element array of mediump int)\r
+0:22 true case is null\r
+0:24 move second child to first child (mediump int)\r
+0:24 'b' (mediump int)\r
+0:24 bitwise and (mediump int)\r
+0:24 'c' (mediump int)\r
+0:24 Constant:\r
+0:24 4 (const int)\r
+0:25 move second child to first child (mediump int)\r
+0:25 'b' (mediump int)\r
+0:25 mod (mediump int)\r
+0:25 'c' (mediump int)\r
+0:25 Constant:\r
+0:25 4 (const int)\r
+0:26 move second child to first child (mediump int)\r
+0:26 'b' (mediump int)\r
+0:26 inclusive-or (mediump int)\r
+0:26 'c' (mediump int)\r
+0:26 Constant:\r
+0:26 4 (const int)\r
+0:27 right shift second child into first child (mediump int)\r
+0:27 'b' (mediump int)\r
+0:27 Constant:\r
+0:27 2 (const int)\r
+0:28 left shift second child into first child (mediump int)\r
+0:28 'b' (mediump int)\r
+0:28 Constant:\r
+0:28 2 (const int)\r
+0:29 mod second child into first child (mediump int)\r
+0:29 'b' (mediump int)\r
+0:29 Constant:\r
+0:29 3 (const int)\r
+0:36 move second child to first child (structure)\r
+0:36 's1' (structure)\r
+0:36 's2' (structure)\r
+0:37 Test condition and select (void)\r
+0:37 Condition\r
+0:37 Compare Equal (bool)\r
+0:37 's1' (structure)\r
+0:37 's2' (structure)\r
+0:37 true case is null\r
+0:38 Test condition and select (void)\r
+0:38 Condition\r
+0:38 Compare Not Equal (bool)\r
+0:38 's1' (structure)\r
+0:38 's2' (structure)\r
+0:38 true case is null\r
+0:40 'b' (mediump int)\r
+0:? Linker Objects\r
+0:? 'a' (3-element array of mediump int)\r
+0:? 'uint' (mediump int)\r
+0:? 'v' (smooth in 3-element array of mediump 4-component vector of float)\r
+0:? 'f' (mediump float)\r
+0:? '__anon__0' (layout(shared ) uniform block)\r
+0:? 'fa' (unsized array of mediump float)\r
+\r
ERROR: 0:9: 'arrayed type' : not supported for this version or the enabled extensions \r
ERROR: 0:11: 'arrayed constructor' : not supported for this version or the enabled extensions \r
ERROR: 0:21: '[' : array index out of range '2'\r
+ERROR: 0:24: 'array assignment' : not supported for this version or the enabled extensions \r
+ERROR: 0:25: 'array assignment' : not supported for this version or the enabled extensions \r
ERROR: 0:25: 'assign' : cannot convert from '4-element array of mediump float' to '5-element array of mediump float'\r
+ERROR: 0:26: 'array assignment' : not supported for this version or the enabled extensions \r
ERROR: 0:26: 'assign' : cannot convert from '4-element array of mediump float' to 'unsized array of mediump float'\r
ERROR: 0:28: 'foo' : no matching overloaded function found \r
ERROR: 0:31: 'arrayed constructor' : not supported for this version or the enabled extensions \r
+ERROR: 0:31: 'array comparison' : not supported for this version or the enabled extensions \r
ERROR: 0:35: '[' : array index out of range '5'\r
ERROR: 0:38: '[' : array index out of range '1000'\r
ERROR: 0:39: '[' : array index out of range '-1'\r
-ERROR: 13 compilation errors. No code generated.\r
+ERROR: 17 compilation errors. No code generated.\r
\r
ERROR: node is still EOpNull!\r
0:9 Function Definition: foo(f1[5]; (4-element array of mediump float)\r
0:35 5.000000\r
0:36 Function Call: foo(f1[5]; (4-element array of mediump float)\r
0:36 'u' (5-element array of mediump float)\r
-0:38 move second child to first child (4-component vector of float)\r
-0:38 direct index (fragColor 4-component vector of float)\r
-0:38 'gl_FragData' (fragColor 32-element array of 4-component vector of float)\r
+0:38 move second child to first child (mediump 4-component vector of float)\r
+0:38 direct index (fragColor mediump 4-component vector of float)\r
+0:38 'gl_FragData' (fragColor 32-element array of mediump 4-component vector of float)\r
0:38 Constant:\r
0:38 1000 (const int)\r
0:38 Constant:\r
0:38 1.000000\r
0:38 1.000000\r
0:38 1.000000\r
-0:39 move second child to first child (4-component vector of float)\r
-0:39 direct index (fragColor 4-component vector of float)\r
-0:39 'gl_FragData' (fragColor 32-element array of 4-component vector of float)\r
+0:39 move second child to first child (mediump 4-component vector of float)\r
+0:39 direct index (fragColor mediump 4-component vector of float)\r
+0:39 'gl_FragData' (fragColor 32-element array of mediump 4-component vector of float)\r
0:39 Constant:\r
0:39 -1 (const int)\r
0:39 Constant:\r
0:39 1.000000\r
0:39 1.000000\r
0:39 1.000000\r
-0:40 move second child to first child (4-component vector of float)\r
-0:40 direct index (fragColor 4-component vector of float)\r
-0:40 'gl_FragData' (fragColor 32-element array of 4-component vector of float)\r
+0:40 move second child to first child (mediump 4-component vector of float)\r
+0:40 direct index (fragColor mediump 4-component vector of float)\r
+0:40 'gl_FragData' (fragColor 32-element array of mediump 4-component vector of float)\r
0:40 Constant:\r
0:40 3 (const int)\r
0:40 Constant:\r
versionsClean.vert
versionsErrors.frag
versionsErrors.vert
+100.frag
120.vert
120.frag
130.frag
virtual bool isMatrix() const { return matrixCols ? true : false; }
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(); }
void setArraySizes(TArraySizes* s)
{
//
//
-// Create strings that declare built-in definitions, add built-ins that
-// cannot be expressed in the files, and establish mappings between
+// Create strings that declare built-in definitions, add built-ins programmatically
+// that cannot be expressed in the strings, and establish mappings between
// 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 "Initialize.h"
TBuiltIns::TBuiltIns()
{
+ // Set up textual representations for making all the permutations
+ // of texturing/imaging functions.
prefixes[EbtFloat] = "";
prefixes[EbtInt] = "i";
prefixes[EbtUint] = "u";
-
postfixes[2] = "2";
postfixes[3] = "3";
postfixes[4] = "4";
+ // Map from symbolic class of texturing dimension to numeric dimensions.
dimMap[Esd1D] = 1;
dimMap[Esd2D] = 2;
dimMap[EsdRect] = 2;
{
}
+//
+// 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)
{
- // TODO: Performance/Memory: consider an extra outer scope for built-ins common across all stages
-
- //
- // Initialize all the built-in strings for parsing.
- //
-
{
//============================================================================
//
//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)
{
TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint };
}
}
+//
+// Helper function for add2ndGenerationSamplingImaging(),
+// when adding context-independent built-in functions.
+//
void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
{
//
s.append(",int);\n");
else
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)
{
// 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)
{
// make one string per stage to contain all functions of the passed-in type for that stage
}
}
+//
+// 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)
{
//
}
}
+//
+// 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)
{
TPrecisionQualifier pq;
}
}
+//
+// 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)
{
- //
- // Set resource-specific built-ins not yet handled.
- //
switch(language) {
case EShLangFragment:
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 {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TString commonBuiltins;
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* prefixes[EbtNumTypes];
int dimMap[EsdNumDims];
//
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);
} else
error(loc, "only the length method is supported for array", field.c_str(), "");
TFunction* TParseContext::handleConstructorCall(TSourceLoc loc, TPublicType& publicType)
{
if (publicType.arraySizes) {
- profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor");
- profileRequires(loc, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor");
+ profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed constructor");
+ profileRequires(loc, EEsProfile, 300, 0, "arrayed constructor");
}
publicType.qualifier.precision = EpqNone;
//
bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualifier)
{
- if (qualifier.storage == EvqConst)
- profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array");
+ if (qualifier.storage == EvqConst) {
+ profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "const array");
+ profileRequires(loc, EEsProfile, 300, 0, "const array");
+ }
if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
requireProfile(loc, ~EEsProfile, "vertex input arrays");
++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.
//
declareArray(loc, identifier, type, variable, newDeclaration);
}
- if (initializer)
- profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
+ if (initializer) {
+ profileRequires(loc, ENoProfile, 120, GL_3DL_array_objects, "initializer");
+ profileRequires(loc, EEsProfile, 300, 0, "initializer");
+ }
} else {
// non-array case
if (! variable)
void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type);
void nestedBlockCheck(TSourceLoc);
void nestedStructCheck(TSourceLoc);
+ void arrayObjectCheck(TSourceLoc, const TType&, const char* op);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
protected:
const char* getPreamble();
- TExtensionBehavior getExtensionBehavior(const char* behavior);
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
void declareArray(TSourceLoc, TString& identifier, const TType&, TVariable*&, bool& newDeclaration);
// 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.
//
-// 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
// particular version in a particular profile, or a stage, or combinations, etc.
//
// will then always continue as if the tested feature was enabled.
//
// 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(),
// 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,
// for some version level). That is, call requireProfile() to constrain the profiles, e.g.:
// profileRequires(loc,
// ECoreProfile | ECompatibilityProfile,
// 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");
//
// This allows the feature if either A) one of the extensions is enabled or
//
// ~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"
//
void TParseContext::initializeExtensionBehavior()
{
- extensionBehavior["GL_ARB_texture_rectangle"] = EBhDisable;
- extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
+ extensionBehavior[GL_ARB_texture_rectangle] = 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)
{
switch (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)
{
switch(stage) {
}
//
-// 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)
{
- TExtensionBehavior behavior = getExtensionBehavior(behaviorString);
- TMap<TString, TExtensionBehavior>:: iterator iter;
- TString msg;
+ // Translate from text string of extension's behavior to an enum.
+ TExtensionBehavior behavior = EBhDisable;
+ 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")) {
+ // special case for the 'all' extension; apply it to every extension present
if (behavior == EBhRequire || behavior == EBhEnable) {
error(currentLoc, "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
return;
iter->second = behavior;
}
} else {
+ // Do the update for this single extension
iter = extensionBehavior.find(TString(extName));
if (iter == extensionBehavior.end()) {
switch (behavior) {
//
//
-// 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 at the same time.
//
EEsProfile = (1 << 3)
} 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_
}\r
}\r
| multiplicative_expression PERCENT unary_expression {\r
+ parseContext.fullIntegerCheck($2.loc, "%");\r
$$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc);\r
if ($$ == 0) {\r
parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString());\r
equality_expression\r
: relational_expression { $$ = $1; }\r
| equality_expression EQ_OP relational_expression {\r
+ parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");\r
$$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc);\r
if ($$ == 0) {\r
parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString());\r
TConstUnionArray unionArray(1);\r
unionArray[0].setBConst(false);\r
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
- } else if (($1->isArray() || $3->isArray()))\r
- parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "==");\r
+ }\r
}\r
| equality_expression NE_OP relational_expression {\r
+ parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");\r
$$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc);\r
if ($$ == 0) {\r
parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString());\r
TConstUnionArray unionArray(1);\r
unionArray[0].setBConst(false);\r
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc);\r
- } else if (($1->isArray() || $3->isArray()))\r
- parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "!=");\r
+ }\r
}\r
;\r
\r
assignment_expression\r
: conditional_expression { $$ = $1; }\r
| unary_expression assignment_operator assignment_expression {\r
+ parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment");\r
parseContext.lValueErrorCheck($2.loc, "assign", $1);\r
$$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc);\r
if ($$ == 0) {\r
parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());\r
$$ = $1;\r
- } else if (($1->isArray() || $3->isArray()))\r
- parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "=");\r
+ }\r
}\r
;\r
\r
assignment_operator\r
- : EQUAL { $$.loc = $1.loc; $$.op = EOpAssign; }\r
- | MUL_ASSIGN { $$.loc = $1.loc; $$.op = EOpMulAssign; }\r
- | DIV_ASSIGN { $$.loc = $1.loc; $$.op = EOpDivAssign; }\r
- | MOD_ASSIGN { $$.loc = $1.loc; $$.op = EOpModAssign; }\r
- | ADD_ASSIGN { $$.loc = $1.loc; $$.op = EOpAddAssign; }\r
- | SUB_ASSIGN { $$.loc = $1.loc; $$.op = EOpSubAssign; }\r
+ : EQUAL {\r
+ $$.loc = $1.loc;\r
+ $$.op = EOpAssign;\r
+ }\r
+ | MUL_ASSIGN {\r
+ $$.loc = $1.loc; \r
+ $$.op = EOpMulAssign;\r
+ }\r
+ | DIV_ASSIGN {\r
+ $$.loc = $1.loc; \r
+ $$.op = EOpDivAssign;\r
+ }\r
+ | MOD_ASSIGN { \r
+ parseContext.fullIntegerCheck($1.loc, "%=");\r
+ $$.loc = $1.loc; \r
+ $$.op = EOpModAssign;\r
+ }\r
+ | ADD_ASSIGN {\r
+ $$.loc = $1.loc; \r
+ $$.op = EOpAddAssign;\r
+ }\r
+ | SUB_ASSIGN {\r
+ $$.loc = $1.loc;\r
+ $$.op = EOpSubAssign;\r
+ }\r
| LEFT_ASSIGN {\r
parseContext.fullIntegerCheck($1.loc, "bit-shift left assign");\r
$$.loc = $1.loc; $$.op = EOpLeftShiftAssign;\r
// Type + name\r
: type_specifier IDENTIFIER {\r
if ($1.arraySizes) {\r
- parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+ parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");\r
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());\r
}\r
}\r
| type_specifier IDENTIFIER array_specifier {\r
if ($1.arraySizes) {\r
- parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+ parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");\r
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());\r
}\r
$$ = $1;\r
\r
if ($1.arraySizes) {\r
- parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+ parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");\r
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
if (parseContext.profile == EEsProfile)\r
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());\r
parseContext.globalQualifierFix($1.loc, $1.qualifier, $2);\r
\r
if ($2.arraySizes) {\r
- parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+ parseContext.profileRequires($2.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");\r
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");\r
if (parseContext.profile == EEsProfile)\r
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());\r
$$.sampler.set(EbtUint, EsdCube, true);\r
}\r
| SAMPLER2DRECT {\r
- parseContext.profileRequires($1.loc, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+ parseContext.profileRequires($1.loc, ENoProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");\r
\r
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
$$.basicType = EbtSampler;\r
$$.sampler.set(EbtFloat, EsdRect);\r
}\r
| SAMPLER2DRECTSHADOW {\r
- parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+ parseContext.profileRequires($1.loc, ECoreProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");\r
\r
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
$$.basicType = EbtSampler;\r
$$.sampler.set(EbtFloat, EsdRect, false, true);\r
}\r
| ISAMPLER2DRECT {\r
- parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+ parseContext.profileRequires($1.loc, ECoreProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");\r
\r
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
$$.basicType = EbtSampler;\r
$$.sampler.set(EbtInt, EsdRect);\r
}\r
| USAMPLER2DRECT {\r
- parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");\r
+ parseContext.profileRequires($1.loc, ECoreProfile, 140, GL_ARB_texture_rectangle, "rectangle texture");\r
\r
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());\r
$$.basicType = EbtSampler;\r
struct_declaration\r
: type_specifier struct_declarator_list SEMICOLON {\r
if ($1.arraySizes) {\r
- parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+ parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");\r
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");\r
if (parseContext.profile == EEsProfile)\r
parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->getSize());\r
}\r
| type_qualifier type_specifier struct_declarator_list SEMICOLON {\r
if ($2.arraySizes) {\r
- parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");\r
+ parseContext.profileRequires($2.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");\r
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");\r
if (parseContext.profile == EEsProfile)\r
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());\r
$$ = $1;\r
}\r
| LEFT_BRACE initializer_list RIGHT_BRACE {\r
+ const char* initFeature = "{ } style initializers";\r
+ parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, initFeature);\r
+ parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shading_language_420pack, initFeature);\r
$$ = $2;\r
}\r
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {\r
+ const char* initFeature = "{ } style initializers";\r
+ parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, initFeature);\r
+ parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shading_language_420pack, initFeature);\r
$$ = $2;\r
}\r
;\r