Commit 3ed2db58 by John Kessenich

Put in correct rules for multiple versions of qualification and typing of inputs…

Put in correct rules for multiple versions of qualification and typing of inputs and outputs. Also, removed EvqAttribute, merging it with EvqVaryingIn. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21064 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent ad3663be
......@@ -23,10 +23,19 @@ in vec2 c2D;
in vec3 c3D;
in vec4 c4D;
in int ic1D;
in ivec2 ic2D;
in ivec3 ic3D;
in ivec4 ic4D;
flat in int ic1D;
flat in ivec2 ic2D;
flat in ivec3 ic3D;
flat in ivec4 ic4D;
in sampler2D bads; // ERROR
struct s {
int i;
sampler2D s; // ERROR
};
out s badout; // ERROR
void main()
{
......
......@@ -7,6 +7,8 @@ uniform mat4x4 m44;
in vec3 v3;
in vec2 v2;
in vec4 bad[10];
void main()
{
int id = gl_VertexID + gl_InstanceID;
......
#version 300 es
in uvec2 t;
in uvec2 badu; // ERROR
flat in uvec2 t;
in float f;
in vec2 tc;
in bool bad; // ERROR
uniform uvec4 v;
uniform int i;
uniform bool b;
......
......@@ -62,9 +62,8 @@ enum TStorageQualifier {
EvqTemporary, // For temporaries (within a function), read/write
EvqGlobal, // For globals read/write
EvqConst, // User defined constants and non-output parameters in functions
EvqAttribute, // Readonly
EvqVaryingIn, // readonly, fragment shaders only
EvqVaryingOut, // vertex shaders only read/write
EvqVaryingIn, // pipeline input, read only
EvqVaryingOut, // pipeline ouput, read/write
EvqUniform, // Readonly, vertex and fragment
// parameters
......@@ -103,9 +102,8 @@ __inline const char* getStorageQualifierString(TStorageQualifier q)
case EvqGlobal: return "global"; break;
case EvqConst: return "const"; break;
case EvqConstReadOnly: return "const (read only)"; break;
case EvqAttribute: return "attribute"; break;
case EvqVaryingIn: return "varying in"; break;
case EvqVaryingOut: return "varying out"; break;
case EvqVaryingIn: return "shader in"; break;
case EvqVaryingOut: return "shader out"; break;
case EvqUniform: return "uniform"; break;
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
......
......@@ -217,6 +217,18 @@ public:
bool restrict : 1;
bool readonly : 1;
bool writeonly : 1;
bool isMemory()
{
return coherent || volatil || restrict || readonly || writeonly;
}
bool isInterpolation()
{
return flat || smooth || nopersp;
}
bool isAuxillary()
{
return centroid || patch || sample;
}
};
class TPublicType {
......
......@@ -328,9 +328,8 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
switch (node->getQualifier().storage) {
case EvqConst: message = "can't modify a const"; break;
case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqAttribute: message = "can't modify an attribute"; break;
case EvqVaryingIn: message = "can't modify shader input"; break;
case EvqUniform: message = "can't modify a uniform"; break;
case EvqVaryingIn: message = "can't modify a varying"; break;
case EvqInstanceId: message = "can't modify gl_InstanceID"; break;
case EvqVertexId: message = "can't modify gl_VertexID"; break;
case EvqFace: message = "can't modify gl_FrontFace"; break;
......@@ -617,7 +616,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
{
if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) {
error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler/image)");
error(line, reason, TType::getBasicString(pType.type), "(structure cannot contain a sampler or image)");
return true;
}
......@@ -632,8 +631,13 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
return false;
}
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier)
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier, const TPublicType& publicType)
{
if (! symbolTable.atGlobalLevel())
return false;
// First, move from parameter qualifiers to shader in/out qualifiers
switch (qualifier.storage) {
case EvqIn:
profileRequires(line, ENoProfile, 130, 0, "in for stage inputs");
......@@ -645,31 +649,68 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
profileRequires(line, EEsProfile, 300, 0, "out for stage outputs");
qualifier.storage = EvqVaryingOut;
break;
case EvqVaryingIn:
case EvqVaryingOut:
break;
case EvqInOut:
qualifier.storage = EvqVaryingIn;
error(line, "cannot use 'inout' at global scope", "", "");
return true;
default: break; // some compilers want this
default:
break;
}
return false;
}
// Do non in/out error checks
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{
if ((pType.qualifier.storage == EvqVaryingIn ||
pType.qualifier.storage == EvqVaryingOut ||
pType.qualifier.storage == EvqAttribute) &&
pType.type == EbtStruct) {
if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
return true;
error(line, "cannot be used with a structure", getStorageQualifierString(pType.qualifier.storage), "");
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
return false;
// now, knowing it is a shader in/out, do all the in/out semantic checks
if (publicType.type == EbtBool) {
error(line, "cannot be bool", getStorageQualifierString(qualifier.storage), "");
return true;
}
if (pType.qualifier.storage != EvqUniform && samplerErrorCheck(line, pType, "samplers and images must be uniform"))
if (language == EShLangVertex && qualifier.storage == EvqVaryingIn) {
if (publicType.type == EbtStruct) {
error(line, "cannot be a structure or array", getStorageQualifierString(qualifier.storage), "");
return true;
}
if (publicType.arraySizes) {
requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays");
profileRequires(line, ENoProfile, 150, 0, "vertex input arrays");
}
}
if (language == EShLangFragment && qualifier.storage == EvqVaryingOut) {
profileRequires(line, EEsProfile, 300, 0, "fragment shader output");
if (publicType.type == EbtStruct) {
error(line, "cannot be a structure", getStorageQualifierString(qualifier.storage), "");
return true;
}
}
if (publicType.type == EbtInt || publicType.type == EbtUint || publicType.type == EbtDouble) {
profileRequires(line, EEsProfile, 300, 0, "shader input/output");
if (language != EShLangVertex && qualifier.storage == EvqVaryingIn && ! qualifier.flat ||
language != EShLangFragment && qualifier.storage == EvqVaryingOut && ! qualifier.flat) {
error(line, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.type));
return true;
}
}
if (language == EShLangVertex && qualifier.storage == EvqVaryingIn &&
(qualifier.isAuxillary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.buffer || qualifier.invariant)) {
error(line, "vertex input cannot be further qualified", "", "");
return true;
}
return false;
}
......@@ -832,13 +873,8 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
//
// Returns true if there is an error.
//
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
bool TParseContext::arrayQualifierErrorCheck(int line, const TPublicType& type)
{
if (type.qualifier.storage == EvqAttribute) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
return true;
}
if (type.qualifier.storage == EvqConst)
profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array");
......@@ -870,7 +906,7 @@ bool TParseContext::arraySizeRequiredErrorCheck(int line, int& size)
//
// Returns true if there was an error.
//
bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
bool TParseContext::arrayErrorCheck(int line, TString& identifier, const TPublicType& type, TVariable*& variable)
{
//
// Don't check for reserved word use until after we know it's not in the symbol table,
......
......@@ -112,15 +112,15 @@ struct TParseContext {
bool globalErrorCheck(int line, bool global, const char* token);
bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
bool arrayQualifierErrorCheck(int line, TPublicType type);
bool arrayQualifierErrorCheck(int line, const TPublicType&);
bool arraySizeRequiredErrorCheck(int line, int& size);
bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
bool arrayErrorCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable);
bool insertBuiltInArrayAtGlobalLevel();
bool voidErrorCheck(int, const TString&, const TPublicType&);
bool boolErrorCheck(int, const TIntermTyped*);
bool boolErrorCheck(int, const TPublicType&);
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(int line, const TPublicType& pType);
bool mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right);
void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier);
......
......@@ -121,7 +121,7 @@ extern void yyerror(const char*);
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
......@@ -147,20 +147,20 @@ extern void yyerror(const char*);
%token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
%token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
%token <lex> IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D
%token <lex> IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D
%token <lex> UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D
%token <lex> IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT
%token <lex> IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT
%token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
%token <lex> IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
%token <lex> IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY
%token <lex> IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY
%token <lex> IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
%token <lex> IMAGECUBEARRAY IIMAGECUBEARRAY UIMAGECUBEARRAY
%token <lex> IMAGE2DMS IIMAGE2DMS UIMAGE2DMS
%token <lex> IMAGE2DMS IIMAGE2DMS UIMAGE2DMS
%token <lex> IMAGE2DMSARRAY IIMAGE2DMSARRAY UIMAGE2DMSARRAY
%token <lex> STRUCT VOID WHILE
%token <lex> IDENTIFIER TYPE_NAME
%token <lex> IDENTIFIER TYPE_NAME
%token <lex> FLOATCONSTANT DOUBLECONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
%token <lex> FIELD_SELECTION
%token <lex> LEFT_OP RIGHT_OP
......@@ -1120,25 +1120,25 @@ assignment_operator
| MOD_ASSIGN { $$.line = $1.line; $$.op = EOpModAssign; }
| ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; }
| SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; }
| LEFT_ASSIGN {
| LEFT_ASSIGN {
parseContext.fullIntegerCheck($1.line, "bit-shift left assign");
$$.line = $1.line; $$.op = EOpLeftShiftAssign;
$$.line = $1.line; $$.op = EOpLeftShiftAssign;
}
| RIGHT_ASSIGN {
parseContext.fullIntegerCheck($1.line, "bit-shift right assign");
$$.line = $1.line; $$.op = EOpRightShiftAssign;
$$.line = $1.line; $$.op = EOpRightShiftAssign;
}
| AND_ASSIGN {
parseContext.fullIntegerCheck($1.line, "bitwise-and assign");
$$.line = $1.line; $$.op = EOpAndAssign;
$$.line = $1.line; $$.op = EOpAndAssign;
}
| XOR_ASSIGN {
parseContext.fullIntegerCheck($1.line, "bitwise-xor assign");
$$.line = $1.line; $$.op = EOpExclusiveOrAssign;
$$.line = $1.line; $$.op = EOpExclusiveOrAssign;
}
| OR_ASSIGN {
parseContext.fullIntegerCheck($1.line, "bitwise-or assign");
$$.line = $1.line; $$.op = EOpInclusiveOrAssign;
$$.line = $1.line; $$.op = EOpInclusiveOrAssign;
}
;
......@@ -1176,7 +1176,7 @@ declaration
}
| PRECISION precision_qualifier type_specifier SEMICOLON {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "precision statement");
// lazy setting of the previous scope's defaults, only takes on first one in a particular scope
parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]);
......@@ -1237,7 +1237,7 @@ function_prototype
}
for (int i = 0; i < prevDec->getParamCount(); ++i) {
if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage) {
parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers",
parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers",
(*$1)[i].type->getStorageQualifierString(), "");
parseContext.recover();
}
......@@ -1298,13 +1298,10 @@ function_header_with_parameters
function_header
: fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) {
parseContext.error($2.line, "no qualifiers allowed for function return",
parseContext.error($2.line, "no qualifiers allowed for function return",
getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover();
}
// make sure a sampler is not involved as well...
if (parseContext.structQualifierErrorCheck($2.line, $1))
parseContext.recover();
// Add the function as a prototype after parsing it (we do not support recursion)
TFunction *function;
......@@ -1327,7 +1324,7 @@ parameter_declarator
}
if (parseContext.reservedErrorCheck($2.line, *$2.string))
parseContext.recover();
TParameter param = {$2.string, new TType($1)};
$$.line = $2.line;
$$.param = param;
......@@ -1381,7 +1378,7 @@ parameter_declaration
$$ = $2;
if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision;
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier.storage, *$$.param.type))
parseContext.recover();
if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type))
......@@ -1410,9 +1407,6 @@ init_declarator_list
}
| init_declarator_list COMMA IDENTIFIER {
$$ = $1;
if (parseContext.structQualifierErrorCheck($3.line, $$.type))
parseContext.recover();
if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $$.type))
parseContext.recover();
......@@ -1420,9 +1414,6 @@ init_declarator_list
parseContext.recover();
}
| init_declarator_list COMMA IDENTIFIER array_specifier {
if (parseContext.structQualifierErrorCheck($3.line, $1.type))
parseContext.recover();
if (parseContext.nonInitConstErrorCheck($3.line, *$3.string, $1.type))
parseContext.recover();
......@@ -1438,9 +1429,6 @@ init_declarator_list
}
}
| init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer {
if (parseContext.structQualifierErrorCheck($3.line, $1.type))
parseContext.recover();
$$ = $1;
TVariable* variable = 0;
......@@ -1469,9 +1457,6 @@ init_declarator_list
}
}
| init_declarator_list COMMA IDENTIFIER EQUAL initializer {
if (parseContext.structQualifierErrorCheck($3.line, $1.type))
parseContext.recover();
$$ = $1;
TIntermNode* intermNode;
......@@ -1494,21 +1479,11 @@ single_declaration
: fully_specified_type {
$$.type = $1;
$$.intermAggregate = 0;
if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier))
parseContext.recover();
}
| fully_specified_type IDENTIFIER {
$$.intermAggregate = 0;
if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier))
parseContext.recover();
$$.type = $1;
if (parseContext.structQualifierErrorCheck($2.line, $$.type))
parseContext.recover();
if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $$.type))
parseContext.recover();
......@@ -1517,13 +1492,6 @@ single_declaration
}
| fully_specified_type IDENTIFIER array_specifier {
$$.intermAggregate = 0;
if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier))
parseContext.recover();
if (parseContext.structQualifierErrorCheck($2.line, $1))
parseContext.recover();
if (parseContext.nonInitConstErrorCheck($2.line, *$2.string, $1))
parseContext.recover();
......@@ -1540,10 +1508,6 @@ single_declaration
}
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
$$.intermAggregate = 0;
if (parseContext.structQualifierErrorCheck($2.line, $1))
parseContext.recover();
$$.type = $1;
TVariable* variable = 0;
......@@ -1572,9 +1536,6 @@ single_declaration
}
}
| fully_specified_type IDENTIFIER EQUAL initializer {
if (parseContext.structQualifierErrorCheck($2.line, $1))
parseContext.recover();
$$.type = $1;
TIntermNode* intermNode;
......@@ -1604,6 +1565,9 @@ fully_specified_type
}
}
| type_qualifier type_specifier {
if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier, $2))
parseContext.recover();
if ($2.arraySizes) {
parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");
......@@ -1614,16 +1578,6 @@ fully_specified_type
$2.arraySizes = 0;
}
if ($1.qualifier.storage == EvqAttribute &&
($2.type == EbtBool || $2.type == EbtInt || $2.type == EbtUint)) {
parseContext.error($2.line, "cannot be bool or int", getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover();
}
if (($1.qualifier.storage == EvqVaryingIn || $1.qualifier.storage == EvqVaryingOut) &&
($2.type == EbtBool || $2.type == EbtInt || $2.type == EbtUint)) {
parseContext.error($2.line, "cannot be bool or int", getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover();
}
$$ = $2;
$$.qualifier = $1.qualifier;
if ($$.qualifier.precision == EpqNone)
......@@ -1747,19 +1701,19 @@ storage_qualifier
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqAttribute;
$$.qualifier.storage = EvqVaryingIn;
}
| VARYING {
parseContext.checkDeprecated($1.line, ENoProfile, 140, "varying");
parseContext.checkDeprecated($1.line, ECoreProfile, 150, "varying");
parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "varying");
parseContext.requireNotRemoved($1.line, EEsProfile, 300, "varying");
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
parseContext.recover();
$$.init($1.line);
if (parseContext.language == EShLangVertex)
if (parseContext.language == EShLangVertex)
$$.qualifier.storage = EvqVaryingOut;
else
$$.qualifier.storage = EvqVaryingIn;
......@@ -1812,7 +1766,7 @@ storage_qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.storage = EvqUniform;
$$.qualifier.buffer = true;
}
| SHARED {
......@@ -2533,7 +2487,7 @@ type_specifier_nonarray
// This is for user defined type names. The lexical phase looked up the
// type.
//
if (TVariable* variable = ($1.symbol)->getAsVariable()) {
if (TVariable* variable = ($1.symbol)->getAsVariable()) {
const TType& structure = variable->getType();
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtStruct;
......@@ -2681,10 +2635,10 @@ initializer
: assignment_expression {
$$ = $1;
}
| LEFT_BRACE initializer_list RIGHT_BRACE {
| LEFT_BRACE initializer_list RIGHT_BRACE {
$$ = $2;
}
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
$$ = $2;
}
;
......@@ -2722,8 +2676,8 @@ simple_statement
compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { parseContext.symbolTable.push(); }
statement_list { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); }
| LEFT_BRACE { parseContext.symbolTable.push(); }
statement_list { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); }
RIGHT_BRACE {
if ($3 != 0)
$3->setOperator(EOpSequence);
......@@ -2790,8 +2744,6 @@ condition
}
| fully_specified_type IDENTIFIER EQUAL initializer {
TIntermNode* intermNode;
if (parseContext.structQualifierErrorCheck($2.line, $1))
parseContext.recover();
if (parseContext.boolErrorCheck($2.line, $1))
parseContext.recover();
......@@ -2829,9 +2781,9 @@ case_label
;
iteration_statement
: WHILE LEFT_PAREN {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
: WHILE LEFT_PAREN {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
}
condition RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
......@@ -2845,10 +2797,10 @@ iteration_statement
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);
--parseContext.loopNestingLevel;
}
| FOR LEFT_PAREN {
| FOR LEFT_PAREN {
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
}
++parseContext.loopNestingLevel;
}
for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
$$ = parseContext.intermediate.makeAggregate($4, $2.line);
......@@ -2980,7 +2932,7 @@ function_definition
// Remember the return type for later checking for RETURN statements.
//
parseContext.currentFunctionType = &(prevDec->getReturnType());
} else
} else
parseContext.currentFunctionType = new TType(EbtVoid);
parseContext.functionReturnsValue = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment