Semantic checks for .length(), switch/case/default, and multidimensional arrays.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22175 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
ef84d10e4c
commit
e369bfccfe
@ -1,15 +1,15 @@
|
|||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
in vec4 i;
|
in vec4 i; // ERROR
|
||||||
out vec4 o;
|
out vec4 o; // ERROR
|
||||||
|
|
||||||
attribute vec2 attv2;
|
attribute vec2 attv2;
|
||||||
attribute vec4 attv4;
|
attribute vec4 attv4;
|
||||||
uniform sampler2D s2D;
|
uniform sampler2D s2D;
|
||||||
invariant varying vec2 centTexCoord;
|
invariant varying vec2 centTexCoord;
|
||||||
invariant gl_Position;
|
invariant gl_Position;
|
||||||
centroid gl_Position;
|
centroid gl_Position; // ERROR
|
||||||
centroid centroid foo;
|
centroid centroid foo; // ERROR
|
||||||
invariant gl_Position, gl_PointSize;
|
invariant gl_Position, gl_PointSize;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
@ -22,11 +22,29 @@ void main()
|
|||||||
gl_Position = b[b.length()-1];
|
gl_Position = b[b.length()-1];
|
||||||
|
|
||||||
float f[];
|
float f[];
|
||||||
int a = f.length();
|
int a1 = f.length(); // ERROR
|
||||||
|
float f[7];
|
||||||
|
int aa = f.length();
|
||||||
|
int a2 = f.length; // ERROR
|
||||||
|
int a3 = f.length(a); // ERROR
|
||||||
|
int a4 = f.flizbit; // ERROR
|
||||||
|
int a4 = f.flizbit(); // ERROR
|
||||||
|
float md[2][4]; // ERROR
|
||||||
|
float[2] md2[4]; // ERROR
|
||||||
|
float[2][4] md3; // ERROR
|
||||||
|
float md5, md6[2][3]; // ERROR
|
||||||
|
float[2] md4, md7[4]; // ERROR
|
||||||
|
float md9[2][3] = float[2][3](1, 2, 3, 4, 5, 6); // ERROR
|
||||||
|
float md10, md11[2][3] = float[2][3](1, 2, 3, 4, 5, 6); // ERROR
|
||||||
|
|
||||||
gl_PointSize = 3.8;
|
gl_PointSize = 3.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
uniform float initted = 3.4;
|
uniform float initted = 3.4; // okay
|
||||||
|
|
||||||
const float concall = sin(0.3);
|
const float concall = sin(0.3);
|
||||||
|
|
||||||
|
int[2][3] foo( // ERROR
|
||||||
|
float[2][3] a, // ERROR
|
||||||
|
float[2] b[3], // ERROR
|
||||||
|
float c[2][3]); // ERROR
|
||||||
|
@ -97,5 +97,11 @@ void main()
|
|||||||
atanh(c3D);
|
atanh(c3D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uniform multi {
|
||||||
|
int[2] a[3]; // ERROR
|
||||||
|
int[2][3] b; // ERROR
|
||||||
|
int c[2][3]; // ERROR
|
||||||
|
} multiInst[2][3]; // ERROR
|
||||||
|
|
||||||
float imageBuffer; // ERROR, reserved
|
float imageBuffer; // ERROR, reserved
|
||||||
float uimage2DRect; // ERROR, reserved
|
float uimage2DRect; // ERROR, reserved
|
||||||
|
@ -18,31 +18,57 @@ void main()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(c)
|
switch(c) // ERROR, not enough stuff after last label
|
||||||
{
|
{
|
||||||
case 2: // ERROR, not enough stuff
|
case 2:
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
f = sin(x); // ERRROR
|
f = sin(x); // ERRROR
|
||||||
case 2: // ERROR, not enough stuff
|
case 2:
|
||||||
f = cos(x);
|
f = cos(x);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
f = sin(x);
|
f = sin(x);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
f = cos(x);
|
f = cos(x);
|
||||||
break;
|
break;
|
||||||
default:
|
default: // ERROR, 2nd default
|
||||||
f = tan(x);
|
f = tan(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 1:
|
||||||
|
f = sin(x);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch (d) {
|
||||||
|
case 1:
|
||||||
|
f = x * x * x;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
f = x * x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
f = tan(x);
|
||||||
|
case 1: // ERROR, 2nd 'case 1'
|
||||||
|
break;
|
||||||
|
case 3.8: // ERROR, non-int
|
||||||
|
break;
|
||||||
|
case c: // ERROR, non-constant
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c) { // a no-error normal switch
|
||||||
case 1:
|
case 1:
|
||||||
f = sin(x);
|
f = sin(x);
|
||||||
break;
|
break;
|
||||||
|
@ -461,10 +461,10 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
|
|||||||
// Both test, and if necessary spit out an error, to see if the node is really
|
// Both test, and if necessary spit out an error, to see if the node is really
|
||||||
// a constant.
|
// a constant.
|
||||||
//
|
//
|
||||||
void TParseContext::constCheck(TIntermTyped* node)
|
void TParseContext::constCheck(TIntermTyped* node, const char* token)
|
||||||
{
|
{
|
||||||
if (node->getQualifier().storage != EvqConst)
|
if (node->getQualifier().storage != EvqConst)
|
||||||
error(node->getLine(), "constant expression required", "", "");
|
error(node->getLine(), "constant expression required", token, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -996,6 +996,28 @@ void TParseContext::arraySizeRequiredCheck(int line, int& size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseContext::arrayDimError(int line)
|
||||||
|
{
|
||||||
|
requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), "arrays of arrays");
|
||||||
|
profileRequires(line, ECoreProfile, 430, 0, "arrays of arrays");
|
||||||
|
profileRequires(line, ECompatibilityProfile, 430, 0, "arrays of arrays");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TParseContext::arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2)
|
||||||
|
{
|
||||||
|
if (sizes1 && sizes2 ||
|
||||||
|
sizes1 && sizes1->size() > 1 ||
|
||||||
|
sizes2 && sizes2->size() > 1)
|
||||||
|
arrayDimError(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TParseContext::arrayDimCheck(int line, const TType* type, TArraySizes sizes2)
|
||||||
|
{
|
||||||
|
if (type && type->isArray() && sizes2 ||
|
||||||
|
sizes2 && sizes2->size() > 1)
|
||||||
|
arrayDimError(line);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Do all the semantic checking for declaring an array, with and
|
// Do all the semantic checking for declaring an array, with and
|
||||||
// without a size, and make the right changes to the symbol table.
|
// without a size, and make the right changes to the symbol table.
|
||||||
@ -1582,6 +1604,8 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arrayDimCheck(line, arraySizes, 0);
|
||||||
|
|
||||||
// check for qualifiers and types that don't belong within a block
|
// check for qualifiers and types that don't belong within a block
|
||||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||||
TQualifier memberQualifier = typeList[member].type->getQualifier();
|
TQualifier memberQualifier = typeList[member].type->getQualifier();
|
||||||
@ -1774,10 +1798,26 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
|
|||||||
statements->setOperator(EOpSequence);
|
statements->setOperator(EOpSequence);
|
||||||
switchSequence->push_back(statements);
|
switchSequence->push_back(statements);
|
||||||
}
|
}
|
||||||
if (branchNode)
|
if (branchNode) {
|
||||||
|
// check all previous cases for the same label (or both are 'default')
|
||||||
|
for (unsigned int s = 0; s < switchSequence->size(); ++s) {
|
||||||
|
TIntermBranch* prevBranch = (*switchSequence)[s]->getAsBranchNode();
|
||||||
|
if (prevBranch) {
|
||||||
|
TIntermTyped* prevExpression = prevBranch->getExpression();
|
||||||
|
TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
|
||||||
|
if (prevExpression == 0 && newExpression == 0)
|
||||||
|
error(branchNode->getLine(), "duplicate label", "default", "");
|
||||||
|
else if (prevExpression != 0 &&
|
||||||
|
newExpression != 0 &&
|
||||||
|
prevExpression->getAsConstantUnion() &&
|
||||||
|
newExpression->getAsConstantUnion() &&
|
||||||
|
prevExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst() ==
|
||||||
|
newExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst())
|
||||||
|
error(branchNode->getLine(), "duplicated value", "case", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
switchSequence->push_back(branchNode);
|
switchSequence->push_back(branchNode);
|
||||||
|
}
|
||||||
// TODO: semantics: verify no duplicated case values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -113,13 +113,16 @@ struct TParseContext {
|
|||||||
void binaryOpError(int line, const char* op, TString left, TString right);
|
void binaryOpError(int line, const char* op, TString left, TString right);
|
||||||
void variableCheck(TIntermTyped*& nodePtr);
|
void variableCheck(TIntermTyped*& nodePtr);
|
||||||
bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
|
bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
|
||||||
void constCheck(TIntermTyped* node);
|
void constCheck(TIntermTyped* node, const char* token);
|
||||||
void integerCheck(TIntermTyped* node, const char* token);
|
void integerCheck(TIntermTyped* node, const char* token);
|
||||||
void globalCheck(int line, bool global, const char* token);
|
void globalCheck(int line, bool global, const char* token);
|
||||||
bool constructorError(int line, TIntermNode*, TFunction&, TOperator, TType&);
|
bool constructorError(int line, TIntermNode*, TFunction&, TOperator, TType&);
|
||||||
void arraySizeCheck(int line, TIntermTyped* expr, int& size);
|
void arraySizeCheck(int line, TIntermTyped* expr, int& size);
|
||||||
bool arrayQualifierError(int line, const TPublicType&);
|
bool arrayQualifierError(int line, const TPublicType&);
|
||||||
void arraySizeRequiredCheck(int line, int& size);
|
void arraySizeRequiredCheck(int line, int& size);
|
||||||
|
void arrayDimError(int line);
|
||||||
|
void arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2);
|
||||||
|
void arrayDimCheck(int line, const TType*, TArraySizes);
|
||||||
void arrayCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable);
|
void arrayCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable);
|
||||||
bool insertBuiltInArrayAtGlobalLevel();
|
bool insertBuiltInArrayAtGlobalLevel();
|
||||||
bool voidErrorCheck(int, const TString&, const TPublicType&);
|
bool voidErrorCheck(int, const TString&, const TPublicType&);
|
||||||
|
@ -82,7 +82,7 @@ const int VersionCount = 12;
|
|||||||
// Each has a different set of built-ins, and we want to preserve that from
|
// Each has a different set of built-ins, and we want to preserve that from
|
||||||
// compile to compile.
|
// compile to compile.
|
||||||
//
|
//
|
||||||
// TODO: quality: thread safety: ensure the built-in symbol table levels are reado only.
|
// TODO: quality: thread safety: ensure the built-in symbol table levels are read only.
|
||||||
TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {};
|
TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {};
|
||||||
|
|
||||||
TPoolAllocator* PerProcessGPA = 0;
|
TPoolAllocator* PerProcessGPA = 0;
|
||||||
|
@ -554,8 +554,6 @@ int yy_input(char* buf, int max_size);
|
|||||||
{D}+"."{D}*({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }
|
{D}+"."{D}*({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }
|
||||||
"."{D}+({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }
|
"."{D}+({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; }
|
||||||
|
|
||||||
"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
|
|
||||||
|
|
||||||
"+=" { pyylval->lex.line = yylineno; return ADD_ASSIGN; }
|
"+=" { pyylval->lex.line = yylineno; return ADD_ASSIGN; }
|
||||||
"-=" { pyylval->lex.line = yylineno; return SUB_ASSIGN; }
|
"-=" { pyylval->lex.line = yylineno; return SUB_ASSIGN; }
|
||||||
"*=" { pyylval->lex.line = yylineno; return MUL_ASSIGN; }
|
"*=" { pyylval->lex.line = yylineno; return MUL_ASSIGN; }
|
||||||
@ -667,7 +665,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon
|
|||||||
char *writeablePreamble = 0;
|
char *writeablePreamble = 0;
|
||||||
if (preamble) {
|
if (preamble) {
|
||||||
// preAmble could be a hard-coded string; make writable copy
|
// preAmble could be a hard-coded string; make writable copy
|
||||||
// TODO: CPP: make it not need writable strings
|
// TODO: efficiency PP: make it not need writable strings
|
||||||
int size = strlen(preamble) + 1;
|
int size = strlen(preamble) + 1;
|
||||||
writeablePreamble = new char[size];
|
writeablePreamble = new char[size];
|
||||||
memcpy(writeablePreamble, preamble, size);
|
memcpy(writeablePreamble, preamble, size);
|
||||||
@ -689,7 +687,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon
|
|||||||
cpp->notAVersionToken = 0;
|
cpp->notAVersionToken = 0;
|
||||||
yylineno = 1;
|
yylineno = 1;
|
||||||
|
|
||||||
// TODO: CPP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens
|
// TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while (argv[0][len] == ' ' ||
|
while (argv[0][len] == ' ' ||
|
||||||
argv[0][len] == '\t' ||
|
argv[0][len] == '\t' ||
|
||||||
@ -886,37 +884,6 @@ int Pa2ndGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE*
|
|||||||
return PaIdentOrType(text, pc, pyylval);
|
return PaIdentOrType(text, pc, pyylval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: CPP: is this dead code? Combine with other comment parsers.
|
|
||||||
int PaParseComment(int& lineno, TParseContext& parseContextLocal)
|
|
||||||
{
|
|
||||||
int transitionFlag = 0;
|
|
||||||
int nextChar;
|
|
||||||
|
|
||||||
while (transitionFlag != 2) {
|
|
||||||
nextChar = yyinput();
|
|
||||||
if (nextChar == '\n')
|
|
||||||
lineno++;
|
|
||||||
switch (nextChar) {
|
|
||||||
case '*' :
|
|
||||||
transitionFlag = 1;
|
|
||||||
break;
|
|
||||||
case '/' : /* if star is the previous character, then it is the end of comment */
|
|
||||||
if (transitionFlag == 1) {
|
|
||||||
return 1 ;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EOF :
|
|
||||||
parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
|
|
||||||
|
|
||||||
return YY_NULL;
|
|
||||||
default : /* Any other character will be a part of the comment */
|
|
||||||
transitionFlag = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void ShPpDebugLogMsg(const char *msg)
|
void ShPpDebugLogMsg(const char *msg)
|
||||||
|
@ -326,7 +326,6 @@ postfix_expression
|
|||||||
TType newType($1->getType());
|
TType newType($1->getType());
|
||||||
newType.dereference();
|
newType.dereference();
|
||||||
$$->setType(newType);
|
$$->setType(newType);
|
||||||
// TODO: testing: write a set of dereference tests
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| function_call {
|
| function_call {
|
||||||
@ -340,8 +339,6 @@ postfix_expression
|
|||||||
// we later see the function calling syntax. Save away the name for now.
|
// we later see the function calling syntax. Save away the name for now.
|
||||||
//
|
//
|
||||||
|
|
||||||
// TODO: semantics: if next token is not "(", then this is an error
|
|
||||||
|
|
||||||
if (*$3.string == "length") {
|
if (*$3.string == "length") {
|
||||||
parseContext.profileRequires($3.line, ENoProfile, 120, "GL_3DL_array_objects", ".length");
|
parseContext.profileRequires($3.line, ENoProfile, 120, "GL_3DL_array_objects", ".length");
|
||||||
$$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line);
|
$$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line);
|
||||||
@ -453,7 +450,8 @@ function_call
|
|||||||
TFunction* fnCall = $1.function;
|
TFunction* fnCall = $1.function;
|
||||||
TOperator op = fnCall->getBuiltInOp();
|
TOperator op = fnCall->getBuiltInOp();
|
||||||
if (op == EOpArrayLength) {
|
if (op == EOpArrayLength) {
|
||||||
// TODO: semantics: check for no arguments to .length()
|
if (fnCall->getParamCount() > 0)
|
||||||
|
parseContext.error($1.line, "method does not accept any arguments", fnCall->getName().c_str(), "");
|
||||||
int length;
|
int length;
|
||||||
if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
|
if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
|
||||||
parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
|
parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
|
||||||
@ -754,7 +752,7 @@ function_identifier
|
|||||||
TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid));
|
TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid));
|
||||||
$$.function = function;
|
$$.function = function;
|
||||||
} else
|
} else
|
||||||
parseContext.error($1->getLine(), "function call, method or subroutine call expected", "", "");
|
parseContext.error($1->getLine(), "function call, method, or subroutine call expected", "", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($$.function == 0) {
|
if ($$.function == 0) {
|
||||||
@ -769,6 +767,8 @@ unary_expression
|
|||||||
: postfix_expression {
|
: postfix_expression {
|
||||||
parseContext.variableCheck($1);
|
parseContext.variableCheck($1);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
if (TIntermMethod* method = $1->getAsMethodNode())
|
||||||
|
parseContext.error($1->getLine(), "incomplete method syntax", method->getMethodName().c_str(), "");
|
||||||
}
|
}
|
||||||
| INC_OP unary_expression {
|
| INC_OP unary_expression {
|
||||||
parseContext.lValueErrorCheck($1.line, "++", $2);
|
parseContext.lValueErrorCheck($1.line, "++", $2);
|
||||||
@ -1086,7 +1086,7 @@ expression
|
|||||||
|
|
||||||
constant_expression
|
constant_expression
|
||||||
: conditional_expression {
|
: conditional_expression {
|
||||||
parseContext.constCheck($1);
|
parseContext.constCheck($1, "");
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -1277,6 +1277,7 @@ parameter_declarator
|
|||||||
parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
|
parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front());
|
||||||
}
|
}
|
||||||
|
parseContext.arrayDimCheck($2.line, $1.arraySizes, $3.arraySizes);
|
||||||
|
|
||||||
parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front());
|
||||||
parseContext.reservedErrorCheck($2.line, *$2.string);
|
parseContext.reservedErrorCheck($2.line, *$2.string);
|
||||||
@ -1346,6 +1347,7 @@ init_declarator_list
|
|||||||
parseContext.nonInitConstCheck($3.line, *$3.string, $1.type);
|
parseContext.nonInitConstCheck($3.line, *$3.string, $1.type);
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($4.line, $4.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($4.line, $4.arraySizes->front());
|
||||||
|
parseContext.arrayDimCheck($3.line, $1.type.arraySizes, $4.arraySizes);
|
||||||
|
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
|
||||||
@ -1363,6 +1365,7 @@ init_declarator_list
|
|||||||
$1.type.arraySizes = $4.arraySizes;
|
$1.type.arraySizes = $4.arraySizes;
|
||||||
parseContext.arrayCheck($4.line, *$3.string, $1.type, variable);
|
parseContext.arrayCheck($4.line, *$3.string, $1.type, variable);
|
||||||
}
|
}
|
||||||
|
parseContext.arrayDimCheck($3.line, $1.type.arraySizes, $4.arraySizes);
|
||||||
|
|
||||||
parseContext.profileRequires($5.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
|
parseContext.profileRequires($5.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
|
||||||
|
|
||||||
@ -1415,6 +1418,7 @@ single_declaration
|
|||||||
parseContext.nonInitConstCheck($2.line, *$2.string, $1);
|
parseContext.nonInitConstCheck($2.line, *$2.string, $1);
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front());
|
||||||
|
parseContext.arrayDimCheck($2.line, $1.arraySizes, $3.arraySizes);
|
||||||
|
|
||||||
$$.type = $1;
|
$$.type = $1;
|
||||||
|
|
||||||
@ -1426,6 +1430,8 @@ single_declaration
|
|||||||
parseContext.updateTypedDefaults($2.line, $$.type.qualifier, $2.string);
|
parseContext.updateTypedDefaults($2.line, $$.type.qualifier, $2.string);
|
||||||
}
|
}
|
||||||
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
|
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
|
||||||
|
parseContext.arrayDimCheck($3.line, $1.arraySizes, $3.arraySizes);
|
||||||
|
|
||||||
$$.intermAggregate = 0;
|
$$.intermAggregate = 0;
|
||||||
$$.type = $1;
|
$$.type = $1;
|
||||||
|
|
||||||
@ -1736,6 +1742,7 @@ type_specifier
|
|||||||
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
|
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
|
||||||
}
|
}
|
||||||
| type_specifier_nonarray array_specifier {
|
| type_specifier_nonarray array_specifier {
|
||||||
|
parseContext.arrayDimCheck($2.line, $2.arraySizes, 0);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
|
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
|
||||||
$$.arraySizes = $2.arraySizes;
|
$$.arraySizes = $2.arraySizes;
|
||||||
@ -2477,9 +2484,11 @@ struct_declaration
|
|||||||
parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1);
|
parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1);
|
||||||
parseContext.precisionQualifierCheck($1.line, $1);
|
parseContext.precisionQualifierCheck($1.line, $1);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < $$->size(); ++i)
|
for (unsigned int i = 0; i < $$->size(); ++i) {
|
||||||
|
parseContext.arrayDimCheck($1.line, (*$$)[i].type, $1.arraySizes);
|
||||||
(*$$)[i].type->mergeType($1);
|
(*$$)[i].type->mergeType($1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
| 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.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
@ -2494,9 +2503,11 @@ struct_declaration
|
|||||||
parseContext.mergeQualifiers($2.line, $2.qualifier, $1.qualifier, true);
|
parseContext.mergeQualifiers($2.line, $2.qualifier, $1.qualifier, true);
|
||||||
parseContext.precisionQualifierCheck($2.line, $2);
|
parseContext.precisionQualifierCheck($2.line, $2);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < $$->size(); ++i)
|
for (unsigned int i = 0; i < $$->size(); ++i) {
|
||||||
|
parseContext.arrayDimCheck($1.line, (*$$)[i].type, $2.arraySizes);
|
||||||
(*$$)[i].type->mergeType($2);
|
(*$$)[i].type->mergeType($2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
struct_declarator_list
|
struct_declarator_list
|
||||||
@ -2518,6 +2529,8 @@ struct_declarator
|
|||||||
| IDENTIFIER array_specifier {
|
| IDENTIFIER array_specifier {
|
||||||
if (parseContext.profile == EEsProfile)
|
if (parseContext.profile == EEsProfile)
|
||||||
parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front());
|
parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front());
|
||||||
|
parseContext.arrayDimCheck($1.line, $2.arraySizes, 0);
|
||||||
|
|
||||||
$$.type = new TType(EbtVoid);
|
$$.type = new TType(EbtVoid);
|
||||||
$$.line = $1.line;
|
$$.line = $1.line;
|
||||||
$$.type->setFieldName(*$1.string);
|
$$.type->setFieldName(*$1.string);
|
||||||
@ -2678,6 +2691,8 @@ switch_statement_list
|
|||||||
|
|
||||||
case_label
|
case_label
|
||||||
: CASE expression COLON {
|
: CASE expression COLON {
|
||||||
|
parseContext.constCheck($2, "case");
|
||||||
|
parseContext.integerCheck($2, "case");
|
||||||
$$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.line);
|
$$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.line);
|
||||||
}
|
}
|
||||||
| DEFAULT COLON {
|
| DEFAULT COLON {
|
||||||
|
@ -78,8 +78,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
// cpp.c
|
// cpp.c
|
||||||
//
|
//
|
||||||
|
|
||||||
// TODO: CPP handle escaped newlines in a // style comment, correctly done in ConsumeWhitespaceComment()
|
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user