Commit cce8965d by Olli Etuaho Committed by Commit Bot

Remove most of the remaining logic from glslang.y

Move most of the logic in glslang.y to ParseContext. This will make it easier to change the code in the future. Only a few specific bits of logic are kept in glslang.y: * Disabling a parsing rule when a given shading language version is being parsed. This makes it easier to check the grammar against the grammar in the GLSL ES specs. * Scoping calls that need to be paired with another call. It's much easier to check these for correctness when the paired calls are next to each other. BUG=angleproject:911 TEST=angle_unittests Change-Id: I52f42a1fc0f28463ca4b237dc6e88345e5173064 Reviewed-on: https://chromium-review.googlesource.com/539640 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 83dde7b9
...@@ -738,7 +738,7 @@ inline const char *getWorkGroupSizeString(size_t dimension) ...@@ -738,7 +738,7 @@ inline const char *getWorkGroupSizeString(size_t dimension)
} }
// //
// This is just for debug print out, carried along with the definitions above. // This is just for debug and error message print out, carried along with the definitions above.
// //
inline const char *getQualifierString(TQualifier q) inline const char *getQualifierString(TQualifier q)
{ {
......
...@@ -569,24 +569,18 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) ...@@ -569,24 +569,18 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
symbolTable.push(); // ESSL3_BUILTINS symbolTable.push(); // ESSL3_BUILTINS
symbolTable.push(); // ESSL3_1_BUILTINS symbolTable.push(); // ESSL3_1_BUILTINS
TPublicType integer;
integer.initializeBasicType(EbtInt);
TPublicType floatingPoint;
floatingPoint.initializeBasicType(EbtFloat);
switch (shaderType) switch (shaderType)
{ {
case GL_FRAGMENT_SHADER: case GL_FRAGMENT_SHADER:
symbolTable.setDefaultPrecision(integer, EbpMedium); symbolTable.setDefaultPrecision(EbtInt, EbpMedium);
break; break;
case GL_VERTEX_SHADER: case GL_VERTEX_SHADER:
symbolTable.setDefaultPrecision(integer, EbpHigh); symbolTable.setDefaultPrecision(EbtInt, EbpHigh);
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); symbolTable.setDefaultPrecision(EbtFloat, EbpHigh);
break; break;
case GL_COMPUTE_SHADER: case GL_COMPUTE_SHADER:
symbolTable.setDefaultPrecision(integer, EbpHigh); symbolTable.setDefaultPrecision(EbtInt, EbpHigh);
symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); symbolTable.setDefaultPrecision(EbtFloat, EbpHigh);
break; break;
default: default:
assert(false && "Language not supported"); assert(false && "Language not supported");
...@@ -603,9 +597,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) ...@@ -603,9 +597,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
// It isn't specified whether Sampler2DRect has default precision. // It isn't specified whether Sampler2DRect has default precision.
initSamplerDefaultPrecision(EbtSampler2DRect); initSamplerDefaultPrecision(EbtSampler2DRect);
TPublicType atomicCounter; symbolTable.setDefaultPrecision(EbtAtomicCounter, EbpHigh);
atomicCounter.initializeBasicType(EbtAtomicCounter);
symbolTable.setDefaultPrecision(atomicCounter, EbpHigh);
InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable); InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
...@@ -617,9 +609,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) ...@@ -617,9 +609,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType) void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
{ {
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd); ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
TPublicType sampler; symbolTable.setDefaultPrecision(samplerType, EbpLow);
sampler.initializeBasicType(samplerType);
symbolTable.setDefaultPrecision(sampler, EbpLow);
} }
void TCompiler::setResourceString() void TCompiler::setResourceString()
......
...@@ -84,36 +84,6 @@ TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node) ...@@ -84,36 +84,6 @@ TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node)
return blockNode; return blockNode;
} }
// For "if" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are in the
// nodePair.
//
// Returns the node created.
TIntermNode *TIntermediate::addIfElse(TIntermTyped *cond,
TIntermNodePair nodePair,
const TSourceLoc &line)
{
// For compile time constant conditions, prune the code now.
if (cond->getAsConstantUnion())
{
if (cond->getAsConstantUnion()->getBConst(0) == true)
{
return EnsureBlock(nodePair.node1);
}
else
{
return EnsureBlock(nodePair.node2);
}
}
TIntermIfElse *node =
new TIntermIfElse(cond, EnsureBlock(nodePair.node1), EnsureBlock(nodePair.node2));
node->setLine(line);
return node;
}
TIntermTyped *TIntermediate::AddComma(TIntermTyped *left, TIntermTyped *TIntermediate::AddComma(TIntermTyped *left,
TIntermTyped *right, TIntermTyped *right,
const TSourceLoc &line, const TSourceLoc &line,
...@@ -225,24 +195,6 @@ TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression, ...@@ -225,24 +195,6 @@ TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression,
return node; return node;
} }
//
// Add branches.
//
TIntermBranch *TIntermediate::addBranch(TOperator branchOp, const TSourceLoc &line)
{
return addBranch(branchOp, 0, line);
}
TIntermBranch *TIntermediate::addBranch(TOperator branchOp,
TIntermTyped *expression,
const TSourceLoc &line)
{
TIntermBranch *node = new TIntermBranch(branchOp, expression);
node->setLine(line);
return node;
}
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate, TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics) TDiagnostics *diagnostics)
{ {
......
...@@ -34,7 +34,6 @@ class TIntermediate ...@@ -34,7 +34,6 @@ class TIntermediate
const TSourceLoc &line, const TSourceLoc &line,
TDiagnostics *diagnostics); TDiagnostics *diagnostics);
static TIntermBlock *EnsureBlock(TIntermNode *node); static TIntermBlock *EnsureBlock(TIntermNode *node);
TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &line);
static TIntermTyped *AddTernarySelection(TIntermTyped *cond, static TIntermTyped *AddTernarySelection(TIntermTyped *cond,
TIntermTyped *trueExpression, TIntermTyped *trueExpression,
TIntermTyped *falseExpression, TIntermTyped *falseExpression,
...@@ -51,8 +50,6 @@ class TIntermediate ...@@ -51,8 +50,6 @@ class TIntermediate
const TType &type, const TType &type,
const TSourceLoc &line); const TSourceLoc &line);
TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
static TIntermTyped *AddSwizzle(TIntermTyped *baseExpression, static TIntermTyped *AddSwizzle(TIntermTyped *baseExpression,
const TVectorFields &fields, const TVectorFields &fields,
const TSourceLoc &dotLocation); const TSourceLoc &dotLocation);
......
...@@ -67,6 +67,25 @@ const char *GetImageArgumentToken(TIntermTyped *imageNode) ...@@ -67,6 +67,25 @@ const char *GetImageArgumentToken(TIntermTyped *imageNode)
return "image"; return "image";
} }
bool CanSetDefaultPrecisionOnType(const TPublicType &type)
{
if (!SupportsPrecision(type.getBasicType()))
{
return false;
}
if (type.getBasicType() == EbtUInt)
{
// ESSL 3.00.4 section 4.5.4
return false;
}
if (type.isAggregate())
{
// Not allowed to set for aggregate types
return false;
}
return true;
}
} // namespace } // namespace
// This tracks each binding point's current default offset for inheritance of subsequent // This tracks each binding point's current default offset for inheritance of subsequent
...@@ -1030,6 +1049,7 @@ void TParseContext::checkIsParameterQualifierValid( ...@@ -1030,6 +1049,7 @@ void TParseContext::checkIsParameterQualifierValid(
const TTypeQualifierBuilder &typeQualifierBuilder, const TTypeQualifierBuilder &typeQualifierBuilder,
TType *type) TType *type)
{ {
// The only parameter qualifiers a parameter can have are in, out, inout or const.
TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(mDiagnostics); TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(mDiagnostics);
if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut) if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut)
...@@ -1839,11 +1859,22 @@ TIntermNode *TParseContext::addLoop(TLoopType type, ...@@ -1839,11 +1859,22 @@ TIntermNode *TParseContext::addLoop(TLoopType type,
} }
if (cond == nullptr || typedCond) if (cond == nullptr || typedCond)
{ {
if (type == ELoopDoWhile)
{
checkIsScalarBool(line, typedCond);
}
// In the case of other loops, it was checked before that the condition is a scalar boolean.
ASSERT(mDiagnostics->numErrors() > 0 || typedCond == nullptr ||
(typedCond->getBasicType() == EbtBool && !typedCond->isArray() &&
!typedCond->isVector()));
node = new TIntermLoop(type, init, typedCond, expr, TIntermediate::EnsureBlock(body)); node = new TIntermLoop(type, init, typedCond, expr, TIntermediate::EnsureBlock(body));
node->setLine(line); node->setLine(line);
return node; return node;
} }
ASSERT(type != ELoopDoWhile);
TIntermDeclaration *declaration = cond->getAsDeclarationNode(); TIntermDeclaration *declaration = cond->getAsDeclarationNode();
ASSERT(declaration); ASSERT(declaration);
TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode(); TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode();
...@@ -1868,6 +1899,32 @@ TIntermNode *TParseContext::addLoop(TLoopType type, ...@@ -1868,6 +1899,32 @@ TIntermNode *TParseContext::addLoop(TLoopType type,
return block; return block;
} }
TIntermNode *TParseContext::addIfElse(TIntermTyped *cond,
TIntermNodePair code,
const TSourceLoc &loc)
{
checkIsScalarBool(loc, cond);
// For compile time constant conditions, prune the code now.
if (cond->getAsConstantUnion())
{
if (cond->getAsConstantUnion()->getBConst(0) == true)
{
return TIntermediate::EnsureBlock(code.node1);
}
else
{
return TIntermediate::EnsureBlock(code.node2);
}
}
TIntermIfElse *node = new TIntermIfElse(cond, TIntermediate::EnsureBlock(code.node1),
TIntermediate::EnsureBlock(code.node2));
node->setLine(loc);
return node;
}
void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier) void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
{ {
checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision, checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
...@@ -2514,6 +2571,25 @@ void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publ ...@@ -2514,6 +2571,25 @@ void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publ
mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset); mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset);
} }
void TParseContext::parseDefaultPrecisionQualifier(const TPrecision precision,
const TPublicType &type,
const TSourceLoc &loc)
{
if ((precision == EbpHigh) && (getShaderType() == GL_FRAGMENT_SHADER) &&
!getFragmentPrecisionHigh())
{
error(loc, "precision is not supported in fragment shader", "highp");
}
if (!CanSetDefaultPrecisionOnType(type))
{
error(loc, "illegal type argument for default precision qualifier",
getBasicString(type.getBasicType()));
return;
}
symbolTable.setDefaultPrecision(type.getBasicType(), precision);
}
void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder) void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
{ {
TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics); TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
...@@ -2919,8 +2995,20 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, ...@@ -2919,8 +2995,20 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
return new TFunction(name, new TType(type)); return new TFunction(name, new TType(type));
} }
TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSourceLoc &loc)
{
checkIsNotReserved(loc, *name);
const TType *returnType = TCache::getType(EbtVoid, EbpUndefined);
return new TFunction(name, returnType);
}
TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType) TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
{ {
if (mShaderVersion < 300 && publicType.array)
{
error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
"[]");
}
if (publicType.isStructSpecifier()) if (publicType.isStructSpecifier())
{ {
error(publicType.getLine(), "constructor can't be a structure definition", error(publicType.getLine(), "constructor can't be a structure definition",
...@@ -2938,6 +3026,32 @@ TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType) ...@@ -2938,6 +3026,32 @@ TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
return new TFunction(nullptr, type, EOpConstruct); return new TFunction(nullptr, type, EOpConstruct);
} }
TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType,
const TString *name,
const TSourceLoc &nameLoc)
{
if (publicType.getBasicType() == EbtVoid)
{
error(nameLoc, "illegal use of type 'void'", name->c_str());
}
checkIsNotReserved(nameLoc, *name);
TType *type = new TType(publicType);
TParameter param = {name, type};
return param;
}
TParameter TParseContext::parseParameterArrayDeclarator(const TString *identifier,
const TSourceLoc &identifierLoc,
TIntermTyped *arraySize,
const TSourceLoc &arrayLoc,
TPublicType *type)
{
checkIsValidTypeForArray(arrayLoc, *type);
unsigned int size = checkIsValidArraySize(arrayLoc, arraySize);
type->setArraySize(size);
return parseParameterDeclarator(*type, identifier, identifierLoc);
}
// This function is used to test for the correctness of the parameters passed to various constructor // This function is used to test for the correctness of the parameters passed to various constructor
// functions and also convert them to the right datatype if it is allowed and required. // functions and also convert them to the right datatype if it is allowed and required.
// //
...@@ -3695,6 +3809,77 @@ TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLo ...@@ -3695,6 +3809,77 @@ TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLo
mShaderVersion); mShaderVersion);
} }
TStorageQualifierWrapper *TParseContext::parseGlobalStorageQualifier(TQualifier qualifier,
const TSourceLoc &loc)
{
checkIsAtGlobalLevel(loc, getQualifierString(qualifier));
return new TStorageQualifierWrapper(qualifier, loc);
}
TStorageQualifierWrapper *TParseContext::parseVaryingQualifier(const TSourceLoc &loc)
{
if (getShaderType() == GL_VERTEX_SHADER)
{
return parseGlobalStorageQualifier(EvqVaryingOut, loc);
}
return parseGlobalStorageQualifier(EvqVaryingIn, loc);
}
TStorageQualifierWrapper *TParseContext::parseInQualifier(const TSourceLoc &loc)
{
if (declaringFunction())
{
return new TStorageQualifierWrapper(EvqIn, loc);
}
if (getShaderType() == GL_FRAGMENT_SHADER)
{
if (mShaderVersion < 300)
{
error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
}
return new TStorageQualifierWrapper(EvqFragmentIn, loc);
}
if (getShaderType() == GL_VERTEX_SHADER)
{
if (mShaderVersion < 300 && !isMultiviewExtensionEnabled())
{
error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
}
return new TStorageQualifierWrapper(EvqVertexIn, loc);
}
return new TStorageQualifierWrapper(EvqComputeIn, loc);
}
TStorageQualifierWrapper *TParseContext::parseOutQualifier(const TSourceLoc &loc)
{
if (declaringFunction())
{
return new TStorageQualifierWrapper(EvqOut, loc);
}
if (mShaderVersion < 300)
{
error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
}
if (getShaderType() != GL_VERTEX_SHADER && getShaderType() != GL_FRAGMENT_SHADER)
{
error(loc, "storage qualifier supported in vertex and fragment shaders only", "out");
}
if (getShaderType() == GL_VERTEX_SHADER)
{
return new TStorageQualifierWrapper(EvqVertexOut, loc);
}
return new TStorageQualifierWrapper(EvqFragmentOut, loc);
}
TStorageQualifierWrapper *TParseContext::parseInOutQualifier(const TSourceLoc &loc)
{
if (!declaringFunction())
{
error(loc, "invalid qualifier: can be only used with function parameters", "inout");
}
return new TStorageQualifierWrapper(EvqInOut, loc);
}
TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
TLayoutQualifier rightQualifier, TLayoutQualifier rightQualifier,
const TSourceLoc &rightQualifierLocation) const TSourceLoc &rightQualifierLocation)
...@@ -3703,6 +3888,27 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif ...@@ -3703,6 +3888,27 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif
mDiagnostics); mDiagnostics);
} }
TField *TParseContext::parseStructDeclarator(TString *identifier, const TSourceLoc &loc)
{
checkIsNotReserved(loc, *identifier);
TType *type = new TType(EbtVoid, EbpUndefined);
return new TField(type, identifier, loc);
}
TField *TParseContext::parseStructArrayDeclarator(TString *identifier,
const TSourceLoc &loc,
TIntermTyped *arraySize,
const TSourceLoc &arraySizeLoc)
{
checkIsNotReserved(loc, *identifier);
TType *type = new TType(EbtVoid, EbpUndefined);
unsigned int size = checkIsValidArraySize(arraySizeLoc, arraySize);
type->setArraySize(size);
return new TField(type, identifier, loc);
}
TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields, TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields, const TFieldList *newlyAddedFields,
const TSourceLoc &location) const TSourceLoc &location)
...@@ -3837,9 +4043,7 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine, ...@@ -3837,9 +4043,7 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
} }
TTypeSpecifierNonArray typeSpecifierNonArray; TTypeSpecifierNonArray typeSpecifierNonArray;
typeSpecifierNonArray.initialize(EbtStruct, structLine); typeSpecifierNonArray.initializeStruct(structureType, true, structLine);
typeSpecifierNonArray.userDef = structureType;
typeSpecifierNonArray.isStructSpecifier = true;
exitStructDeclaration(); exitStructDeclaration();
return typeSpecifierNonArray; return typeSpecifierNonArray;
...@@ -3979,6 +4183,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, ...@@ -3979,6 +4183,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
{ {
ASSERT(op != EOpNull);
TIntermTyped *node = createUnaryMath(op, child, loc); TIntermTyped *node = createUnaryMath(op, child, loc);
if (node == nullptr) if (node == nullptr)
{ {
...@@ -4397,6 +4602,7 @@ TIntermTyped *TParseContext::addAssign(TOperator op, ...@@ -4397,6 +4602,7 @@ TIntermTyped *TParseContext::addAssign(TOperator op,
TIntermTyped *right, TIntermTyped *right,
const TSourceLoc &loc) const TSourceLoc &loc)
{ {
checkCanBeLValue(loc, "assign", left);
TIntermTyped *node = createAssign(op, left, right, loc); TIntermTyped *node = createAssign(op, left, right, loc);
if (node == nullptr) if (node == nullptr)
{ {
...@@ -4447,28 +4653,39 @@ TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) ...@@ -4447,28 +4653,39 @@ TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
error(loc, "non-void function must return a value", "return"); error(loc, "non-void function must return a value", "return");
} }
break; break;
case EOpKill:
if (mShaderType != GL_FRAGMENT_SHADER)
{
error(loc, "discard supported in fragment shaders only", "discard");
}
break;
default: default:
// No checks for discard UNREACHABLE();
break; break;
} }
return intermediate.addBranch(op, loc); return addBranch(op, nullptr, loc);
} }
TIntermBranch *TParseContext::addBranch(TOperator op, TIntermBranch *TParseContext::addBranch(TOperator op,
TIntermTyped *returnValue, TIntermTyped *expression,
const TSourceLoc &loc) const TSourceLoc &loc)
{ {
ASSERT(op == EOpReturn); if (expression != nullptr)
mFunctionReturnsValue = true;
if (mCurrentFunctionType->getBasicType() == EbtVoid)
{
error(loc, "void function cannot return a value", "return");
}
else if (*mCurrentFunctionType != returnValue->getType())
{ {
error(loc, "function return is not matching type:", "return"); ASSERT(op == EOpReturn);
mFunctionReturnsValue = true;
if (mCurrentFunctionType->getBasicType() == EbtVoid)
{
error(loc, "void function cannot return a value", "return");
}
else if (*mCurrentFunctionType != expression->getType())
{
error(loc, "function return is not matching type:", "return");
}
} }
return intermediate.addBranch(op, returnValue, loc); TIntermBranch *node = new TIntermBranch(op, expression);
node->setLine(loc);
return node;
} }
void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall) void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall)
......
...@@ -193,6 +193,10 @@ class TParseContext : angle::NonCopyable ...@@ -193,6 +193,10 @@ class TParseContext : angle::NonCopyable
TIntermNode *body, TIntermNode *body,
const TSourceLoc &loc); const TSourceLoc &loc);
// For "if" test nodes. There are three children: a condition, a true path, and a false path.
// The two paths are in TIntermNodePair code.
TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
void addFullySpecifiedType(TPublicType *typeSpecifier); void addFullySpecifiedType(TPublicType *typeSpecifier);
TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
const TPublicType &typeSpecifier); const TPublicType &typeSpecifier);
...@@ -254,7 +258,11 @@ class TParseContext : angle::NonCopyable ...@@ -254,7 +258,11 @@ class TParseContext : angle::NonCopyable
TIntermTyped *initializer, TIntermTyped *initializer,
TIntermDeclaration *declarationOut); TIntermDeclaration *declarationOut);
void parseDefaultPrecisionQualifier(const TPrecision precision,
const TPublicType &type,
const TSourceLoc &loc);
void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder); void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction, TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
const TSourceLoc &location); const TSourceLoc &location);
TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype, TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
...@@ -267,7 +275,16 @@ class TParseContext : angle::NonCopyable ...@@ -267,7 +275,16 @@ class TParseContext : angle::NonCopyable
TFunction *parseFunctionHeader(const TPublicType &type, TFunction *parseFunctionHeader(const TPublicType &type,
const TString *name, const TString *name,
const TSourceLoc &location); const TSourceLoc &location);
TFunction *addNonConstructorFunc(const TString *name, const TSourceLoc &loc);
TFunction *addConstructorFunc(const TPublicType &publicType); TFunction *addConstructorFunc(const TPublicType &publicType);
TParameter parseParameterDeclarator(const TPublicType &publicType,
const TString *name,
const TSourceLoc &nameLoc);
TParameter parseParameterArrayDeclarator(const TString *identifier,
const TSourceLoc &identifierLoc,
TIntermTyped *arraySize,
const TSourceLoc &arrayLoc,
TPublicType *type);
TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc &location, const TSourceLoc &location,
...@@ -277,6 +294,13 @@ class TParseContext : angle::NonCopyable ...@@ -277,6 +294,13 @@ class TParseContext : angle::NonCopyable
const TString &fieldString, const TString &fieldString,
const TSourceLoc &fieldLocation); const TSourceLoc &fieldLocation);
// Parse declarator for a single field
TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc);
TField *parseStructArrayDeclarator(TString *identifier,
const TSourceLoc &loc,
TIntermTyped *arraySize,
const TSourceLoc &arraySizeLoc);
TFieldList *combineStructFieldLists(TFieldList *processedFields, TFieldList *combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields, const TFieldList *newlyAddedFields,
const TSourceLoc &location); const TSourceLoc &location);
...@@ -317,6 +341,12 @@ class TParseContext : angle::NonCopyable ...@@ -317,6 +341,12 @@ class TParseContext : angle::NonCopyable
int intValue, int intValue,
const TSourceLoc &intValueLine); const TSourceLoc &intValueLine);
TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc); TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
const TSourceLoc &loc);
TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
TLayoutQualifier rightQualifier, TLayoutQualifier rightQualifier,
const TSourceLoc &rightQualifierLocation); const TSourceLoc &rightQualifierLocation);
...@@ -351,7 +381,7 @@ class TParseContext : angle::NonCopyable ...@@ -351,7 +381,7 @@ class TParseContext : angle::NonCopyable
TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
void checkTextureOffsetConst(TIntermAggregate *functionCall); void checkTextureOffsetConst(TIntermAggregate *functionCall);
void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall); void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
......
...@@ -130,8 +130,8 @@ struct TConstParameter ...@@ -130,8 +130,8 @@ struct TConstParameter
TConstParameter(const TString *n, TType *t) = delete; TConstParameter(const TString *n, TType *t) = delete;
TConstParameter(TString *n, const TType *t) = delete; TConstParameter(TString *n, const TType *t) = delete;
const TString *name; const TString *const name;
const TType *type; const TType *const type;
}; };
// The function sub-class of symbols and the parser will need to // The function sub-class of symbols and the parser will need to
...@@ -150,7 +150,7 @@ struct TParameter ...@@ -150,7 +150,7 @@ struct TParameter
return TConstParameter(constName, constType); return TConstParameter(constName, constType);
} }
TString *name; const TString *name;
TType *type; TType *type;
}; };
...@@ -446,18 +446,11 @@ class TSymbolTable : angle::NonCopyable ...@@ -446,18 +446,11 @@ class TSymbolTable : angle::NonCopyable
void dump(TInfoSink &infoSink) const; void dump(TInfoSink &infoSink) const;
bool setDefaultPrecision(const TPublicType &type, TPrecision prec) void setDefaultPrecision(TBasicType type, TPrecision prec)
{ {
if (!SupportsPrecision(type.getBasicType()))
return false;
if (type.getBasicType() == EbtUInt)
return false; // ESSL 3.00.4 section 4.5.4
if (type.isAggregate())
return false; // Not allowed to set for aggregate types
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
// Uses map operator [], overwrites the current value // Uses map operator [], overwrites the current value
(*precisionStack[indexOfLastElement])[type.getBasicType()] = prec; (*precisionStack[indexOfLastElement])[type] = prec;
return true;
} }
// Searches down the precisionStack for a precision qualifier // Searches down the precisionStack for a precision qualifier
......
...@@ -242,9 +242,9 @@ class TType ...@@ -242,9 +242,9 @@ class TType
{ {
} }
explicit TType(const TPublicType &p); explicit TType(const TPublicType &p);
explicit TType(TStructure *userDef, TPrecision p = EbpUndefined) explicit TType(TStructure *userDef)
: type(EbtStruct), : type(EbtStruct),
precision(p), precision(EbpUndefined),
qualifier(EvqTemporary), qualifier(EvqTemporary),
invariant(false), invariant(false),
memoryQualifier(TMemoryQualifier::create()), memoryQualifier(TMemoryQualifier::create()),
...@@ -525,16 +525,27 @@ struct TTypeSpecifierNonArray ...@@ -525,16 +525,27 @@ struct TTypeSpecifierNonArray
// true if the type was defined by a struct specifier rather than a reference to a type name. // true if the type was defined by a struct specifier rather than a reference to a type name.
bool isStructSpecifier; bool isStructSpecifier;
void initialize(TBasicType bt, const TSourceLoc &ln) void initialize(TBasicType aType, const TSourceLoc &aLine)
{ {
type = bt; ASSERT(aType != EbtStruct);
type = aType;
primarySize = 1; primarySize = 1;
secondarySize = 1; secondarySize = 1;
userDef = nullptr; userDef = nullptr;
line = ln; line = aLine;
isStructSpecifier = false; isStructSpecifier = false;
} }
void initializeStruct(TType *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine)
{
type = EbtStruct;
primarySize = 1;
secondarySize = 1;
userDef = aUserDef;
line = aLine;
isStructSpecifier = aIsStructSpecifier;
}
void setAggregate(unsigned char size) { primarySize = size; } void setAggregate(unsigned char size) { primarySize = size; }
void setMatrix(unsigned char columns, unsigned char rows) void setMatrix(unsigned char columns, unsigned char rows)
......
...@@ -123,49 +123,37 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -123,49 +123,37 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
#define VERTEX_ONLY(S, L) { \ #define VERTEX_ONLY(S, L) { \
if (context->getShaderType() != GL_VERTEX_SHADER) { \ if (context->getShaderType() != GL_VERTEX_SHADER) { \
context->error(L, " supported in vertex shaders only ", S); \ context->error(L, " supported in vertex shaders only", S); \
} \
}
#define FRAG_ONLY(S, L) { \
if (context->getShaderType() != GL_FRAGMENT_SHADER) { \
context->error(L, " supported in fragment shaders only ", S); \
} \ } \
} }
#define COMPUTE_ONLY(S, L) { \ #define COMPUTE_ONLY(S, L) { \
if (context->getShaderType() != GL_COMPUTE_SHADER) { \ if (context->getShaderType() != GL_COMPUTE_SHADER) { \
context->error(L, " supported in compute shaders only ", S); \ context->error(L, " supported in compute shaders only", S); \
} \
}
#define NON_COMPUTE_ONLY(S, L) { \
if (context->getShaderType() != GL_VERTEX_SHADER && context->getShaderType() != GL_FRAGMENT_SHADER) { \
context->error(L, " supported in vertex and fragment shaders only ", S); \
} \ } \
} }
#define ES2_ONLY(S, L) { \ #define ES2_ONLY(S, L) { \
if (context->getShaderVersion() != 100) { \ if (context->getShaderVersion() != 100) { \
context->error(L, " supported in GLSL ES 1.00 only ", S); \ context->error(L, " supported in GLSL ES 1.00 only", S); \
} \ } \
} }
#define ES3_OR_NEWER(TOKEN, LINE, REASON) { \ #define ES3_OR_NEWER(TOKEN, LINE, REASON) { \
if (context->getShaderVersion() < 300) { \ if (context->getShaderVersion() < 300) { \
context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN); \ context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \
} \ } \
} }
#define ES3_OR_NEWER_OR_MULTIVIEW(TOKEN, LINE, REASON) { \ #define ES3_OR_NEWER_OR_MULTIVIEW(TOKEN, LINE, REASON) { \
if (context->getShaderVersion() < 300 && !context->isMultiviewExtensionEnabled()) { \ if (context->getShaderVersion() < 300 && !context->isMultiviewExtensionEnabled()) { \
context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN); \ context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \
} \ } \
} }
#define ES3_1_ONLY(TOKEN, LINE, REASON) { \ #define ES3_1_ONLY(TOKEN, LINE, REASON) { \
if (context->getShaderVersion() != 310) { \ if (context->getShaderVersion() != 310) { \
context->error(LINE, REASON " supported in GLSL ES 3.10 only ", TOKEN); \ context->error(LINE, REASON " supported in GLSL ES 3.10 only", TOKEN); \
} \ } \
} }
%} %}
...@@ -204,7 +192,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -204,7 +192,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
%type <lex> identifier %type <lex> identifier
%type <interm> assignment_operator unary_operator %type <interm.op> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression %type <interm.intermTypedNode> expression integer_expression assignment_expression
%type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression %type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
...@@ -227,7 +215,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -227,7 +215,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope %type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
%type <interm> single_declaration init_declarator_list %type <interm> single_declaration init_declarator_list
%type <interm> parameter_declaration parameter_declarator parameter_type_specifier %type <interm.param> parameter_declaration parameter_declarator parameter_type_specifier
%type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id %type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id
%type <interm.type> fully_specified_type type_specifier %type <interm.type> fully_specified_type type_specifier
...@@ -391,22 +379,13 @@ function_call_header ...@@ -391,22 +379,13 @@ function_call_header
function_identifier function_identifier
: type_specifier_no_prec { : type_specifier_no_prec {
if ($1.array) {
ES3_OR_NEWER("[]", @1, "array constructor");
}
$$ = context->addConstructorFunc($1); $$ = context->addConstructorFunc($1);
} }
| IDENTIFIER { | IDENTIFIER {
context->checkIsNotReserved(@1, *$1.string); $$ = context->addNonConstructorFunc($1.string, @1);
const TType *type = TCache::getType(EbtVoid, EbpUndefined);
TFunction *function = new TFunction($1.string, type);
$$ = function;
} }
| FIELD_SELECTION { | FIELD_SELECTION {
context->checkIsNotReserved(@1, *$1.string); $$ = context->addNonConstructorFunc($1.string, @1);
const TType *type = TCache::getType(EbtVoid, EbpUndefined);
TFunction *function = new TFunction($1.string, type);
$$ = function;
} }
; ;
...@@ -421,21 +400,18 @@ unary_expression ...@@ -421,21 +400,18 @@ unary_expression
$$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1); $$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1);
} }
| unary_operator unary_expression { | unary_operator unary_expression {
if ($1.op != EOpNull) { $$ = context->addUnaryMath($1, $2, @1);
$$ = context->addUnaryMath($1.op, $2, @1);
} else
$$ = $2;
} }
; ;
// Grammar Note: No traditional style type casts. // Grammar Note: No traditional style type casts.
unary_operator unary_operator
: PLUS { $$.op = EOpPositive; } : PLUS { $$ = EOpPositive; }
| DASH { $$.op = EOpNegative; } | DASH { $$ = EOpNegative; }
| BANG { $$.op = EOpLogicalNot; } | BANG { $$ = EOpLogicalNot; }
| TILDE { | TILDE {
ES3_OR_NEWER("~", @$, "bit-wise operator"); ES3_OR_NEWER("~", @$, "bit-wise operator");
$$.op = EOpBitwiseNot; $$ = EOpBitwiseNot;
} }
; ;
// Grammar Note: No '*' or '&' unary ops. Pointers are not supported. // Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
...@@ -557,40 +533,39 @@ conditional_expression ...@@ -557,40 +533,39 @@ conditional_expression
assignment_expression assignment_expression
: conditional_expression { $$ = $1; } : conditional_expression { $$ = $1; }
| unary_expression assignment_operator assignment_expression { | unary_expression assignment_operator assignment_expression {
context->checkCanBeLValue(@2, "assign", $1); $$ = context->addAssign($2, $1, $3, @2);
$$ = context->addAssign($2.op, $1, $3, @2);
} }
; ;
assignment_operator assignment_operator
: EQUAL { $$.op = EOpAssign; } : EQUAL { $$ = EOpAssign; }
| MUL_ASSIGN { $$.op = EOpMulAssign; } | MUL_ASSIGN { $$ = EOpMulAssign; }
| DIV_ASSIGN { $$.op = EOpDivAssign; } | DIV_ASSIGN { $$ = EOpDivAssign; }
| MOD_ASSIGN { | MOD_ASSIGN {
ES3_OR_NEWER("%=", @$, "integer modulus operator"); ES3_OR_NEWER("%=", @$, "integer modulus operator");
$$.op = EOpIModAssign; $$ = EOpIModAssign;
} }
| ADD_ASSIGN { $$.op = EOpAddAssign; } | ADD_ASSIGN { $$ = EOpAddAssign; }
| SUB_ASSIGN { $$.op = EOpSubAssign; } | SUB_ASSIGN { $$ = EOpSubAssign; }
| LEFT_ASSIGN { | LEFT_ASSIGN {
ES3_OR_NEWER("<<=", @$, "bit-wise operator"); ES3_OR_NEWER("<<=", @$, "bit-wise operator");
$$.op = EOpBitShiftLeftAssign; $$ = EOpBitShiftLeftAssign;
} }
| RIGHT_ASSIGN { | RIGHT_ASSIGN {
ES3_OR_NEWER(">>=", @$, "bit-wise operator"); ES3_OR_NEWER(">>=", @$, "bit-wise operator");
$$.op = EOpBitShiftRightAssign; $$ = EOpBitShiftRightAssign;
} }
| AND_ASSIGN { | AND_ASSIGN {
ES3_OR_NEWER("&=", @$, "bit-wise operator"); ES3_OR_NEWER("&=", @$, "bit-wise operator");
$$.op = EOpBitwiseAndAssign; $$ = EOpBitwiseAndAssign;
} }
| XOR_ASSIGN { | XOR_ASSIGN {
ES3_OR_NEWER("^=", @$, "bit-wise operator"); ES3_OR_NEWER("^=", @$, "bit-wise operator");
$$.op = EOpBitwiseXorAssign; $$ = EOpBitwiseXorAssign;
} }
| OR_ASSIGN { | OR_ASSIGN {
ES3_OR_NEWER("|=", @$, "bit-wise operator"); ES3_OR_NEWER("|=", @$, "bit-wise operator");
$$.op = EOpBitwiseOrAssign; $$ = EOpBitwiseOrAssign;
} }
; ;
...@@ -625,13 +600,8 @@ declaration ...@@ -625,13 +600,8 @@ declaration
$$ = $1.intermDeclaration; $$ = $1.intermDeclaration;
} }
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->parseDefaultPrecisionQualifier($2, $3, @1);
context->error(@1, "precision is not supported in fragment shader", "highp"); $$ = nullptr;
}
if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.getBasicType()));
}
$$ = 0;
} }
| type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks");
...@@ -647,7 +617,7 @@ declaration ...@@ -647,7 +617,7 @@ declaration
} }
| type_qualifier SEMICOLON { | type_qualifier SEMICOLON {
context->parseGlobalLayoutQualifier(*$1); context->parseGlobalLayoutQualifier(*$1);
$$ = 0; $$ = nullptr;
} }
| type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant
{ {
...@@ -676,26 +646,23 @@ function_header_with_parameters ...@@ -676,26 +646,23 @@ function_header_with_parameters
: function_header parameter_declaration { : function_header parameter_declaration {
// Add the parameter // Add the parameter
$$ = $1; $$ = $1;
if ($2.param.type->getBasicType() != EbtVoid) if ($2.type->getBasicType() != EbtVoid)
$1->addParameter($2.param.turnToConst()); {
else $1->addParameter($2.turnToConst());
delete $2.param.type; }
} }
| function_header_with_parameters COMMA parameter_declaration { | function_header_with_parameters COMMA parameter_declaration {
// $$ = $1;
// Only first parameter of one-parameter functions can be void // Only first parameter of one-parameter functions can be void
// The check for named parameters not being void is done in parameter_declarator // The check for named parameters not being void is done in parameter_declarator
// if ($3.type->getBasicType() == EbtVoid)
if ($3.param.type->getBasicType() == EbtVoid) { {
//
// This parameter > first is void // This parameter > first is void
// context->error(@2, "cannot be a parameter type except for '(void)'", "void");
context->error(@2, "cannot be an argument type except for '(void)'", "void"); }
delete $3.param.type; else
} else { {
// Add the parameter $1->addParameter($3.turnToConst());
$$ = $1;
$1->addParameter($3.param.turnToConst());
} }
} }
; ;
...@@ -712,60 +679,36 @@ function_header ...@@ -712,60 +679,36 @@ function_header
parameter_declarator parameter_declarator
// Type + name // Type + name
: type_specifier identifier { : type_specifier identifier {
if ($1.getBasicType() == EbtVoid) { $$ = context->parseParameterDeclarator($1, $2.string, @2);
context->error(@2, "illegal use of type 'void'", $2.string->c_str());
}
context->checkIsNotReserved(@2, *$2.string);
TParameter param = {$2.string, new TType($1)};
$$.param = param;
} }
| type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
// Check that we can make an array out of this type $$ = context->parseParameterArrayDeclarator($2.string, @2, $4, @3, &$1);
context->checkIsValidTypeForArray(@3, $1);
context->checkIsNotReserved(@2, *$2.string);
unsigned int size = context->checkIsValidArraySize(@3, $4);
$1.setArraySize(size);
TType* type = new TType($1);
TParameter param = { $2.string, type };
$$.param = param;
} }
; ;
parameter_declaration parameter_declaration
//
// The only parameter qualifier a parameter can have are
// IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
//
//
// Type + name
//
: type_qualifier parameter_declarator { : type_qualifier parameter_declarator {
$$ = $2; $$ = $2;
context->checkIsParameterQualifierValid(@2, *$1, $2.param.type); context->checkIsParameterQualifierValid(@2, *$1, $2.type);
} }
| parameter_declarator { | parameter_declarator {
$$ = $1; $$ = $1;
$$.param.type->setQualifier(EvqIn); $$.type->setQualifier(EvqIn);
} }
| type_qualifier parameter_type_specifier { | type_qualifier parameter_type_specifier {
$$ = $2; $$ = $2;
context->checkIsParameterQualifierValid(@2, *$1, $2.param.type); context->checkIsParameterQualifierValid(@2, *$1, $2.type);
} }
| parameter_type_specifier { | parameter_type_specifier {
$$ = $1; $$ = $1;
$$.param.type->setQualifier(EvqIn); $$.type->setQualifier(EvqIn);
} }
; ;
parameter_type_specifier parameter_type_specifier
: type_specifier { : type_specifier {
TParameter param = { 0, new TType($1) }; TParameter param = { 0, new TType($1) };
$$.param = param; $$ = param;
} }
; ;
...@@ -889,73 +832,30 @@ storage_qualifier ...@@ -889,73 +832,30 @@ storage_qualifier
ATTRIBUTE { ATTRIBUTE {
VERTEX_ONLY("attribute", @1); VERTEX_ONLY("attribute", @1);
ES2_ONLY("attribute", @1); ES2_ONLY("attribute", @1);
context->checkIsAtGlobalLevel(@1, "attribute"); $$ = context->parseGlobalStorageQualifier(EvqAttribute, @1);
$$ = new TStorageQualifierWrapper(EvqAttribute, @1);
} }
| VARYING { | VARYING {
ES2_ONLY("varying", @1); ES2_ONLY("varying", @1);
context->checkIsAtGlobalLevel(@1, "varying"); $$ = context->parseVaryingQualifier(@1);
if (context->getShaderType() == GL_VERTEX_SHADER)
$$ = new TStorageQualifierWrapper(EvqVaryingOut, @1);
else
$$ = new TStorageQualifierWrapper(EvqVaryingIn, @1);
} }
| CONST_QUAL { | CONST_QUAL {
$$ = new TStorageQualifierWrapper(EvqConst, @1); $$ = new TStorageQualifierWrapper(EvqConst, @1);
} }
| IN_QUAL { | IN_QUAL {
if (context->declaringFunction()) $$ = context->parseInQualifier(@1);
{
$$ = new TStorageQualifierWrapper(EvqIn, @1);
}
else if (context->getShaderType() == GL_FRAGMENT_SHADER)
{
ES3_OR_NEWER("in", @1, "storage qualifier");
$$ = new TStorageQualifierWrapper(EvqFragmentIn, @1);
}
else if (context->getShaderType() == GL_VERTEX_SHADER)
{
ES3_OR_NEWER_OR_MULTIVIEW("in", @1, "storage qualifier");
$$ = new TStorageQualifierWrapper(EvqVertexIn, @1);
}
else
{
$$ = new TStorageQualifierWrapper(EvqComputeIn, @1);
}
} }
| OUT_QUAL { | OUT_QUAL {
if (context->declaringFunction()) $$ = context->parseOutQualifier(@1);
{
$$ = new TStorageQualifierWrapper(EvqOut, @1);
}
else
{
ES3_OR_NEWER("out", @1, "storage qualifier");
NON_COMPUTE_ONLY("out", @1);
if (context->getShaderType() == GL_FRAGMENT_SHADER)
{
$$ = new TStorageQualifierWrapper(EvqFragmentOut, @1);
}
else
{
$$ = new TStorageQualifierWrapper(EvqVertexOut, @1);
}
}
} }
| INOUT_QUAL { | INOUT_QUAL {
if (!context->declaringFunction()) $$ = context->parseInOutQualifier(@1);
{
context->error(@1, "invalid qualifier: can be only used with function parameters", "inout");
}
$$ = new TStorageQualifierWrapper(EvqInOut, @1);
} }
| CENTROID { | CENTROID {
ES3_OR_NEWER("centroid", @1, "storage qualifier"); ES3_OR_NEWER("centroid", @1, "storage qualifier");
$$ = new TStorageQualifierWrapper(EvqCentroid, @1); $$ = new TStorageQualifierWrapper(EvqCentroid, @1);
} }
| UNIFORM { | UNIFORM {
context->checkIsAtGlobalLevel(@1, "uniform"); $$ = context->parseGlobalStorageQualifier(EvqUniform, @1);
$$ = new TStorageQualifierWrapper(EvqUniform, @1);
} }
| READONLY { | READONLY {
$$ = new TMemoryQualifierWrapper(EvqReadOnly, @1); $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1);
...@@ -973,9 +873,8 @@ storage_qualifier ...@@ -973,9 +873,8 @@ storage_qualifier
$$ = new TMemoryQualifierWrapper(EvqVolatile, @1); $$ = new TMemoryQualifierWrapper(EvqVolatile, @1);
} }
| SHARED { | SHARED {
context->checkIsAtGlobalLevel(@1, "shared");
COMPUTE_ONLY("shared", @1); COMPUTE_ONLY("shared", @1);
$$ = new TStorageQualifierWrapper(EvqShared, @1); $$ = context->parseGlobalStorageQualifier(EvqShared, @1);
} }
; ;
...@@ -1270,13 +1169,9 @@ type_specifier_nonarray ...@@ -1270,13 +1169,9 @@ type_specifier_nonarray
$$.initialize(EbtAtomicCounter, @1); $$.initialize(EbtAtomicCounter, @1);
} }
| TYPE_NAME { | TYPE_NAME {
// // This is for user defined type names. The lexical phase looked up the type.
// This is for user defined type names. The lexical phase looked up the
// type.
//
TType& structure = static_cast<TVariable*>($1.symbol)->getType(); TType& structure = static_cast<TVariable*>($1.symbol)->getType();
$$.initialize(EbtStruct, @1); $$.initializeStruct(&structure, false, @1);
$$.userDef = &structure;
} }
; ;
...@@ -1320,19 +1215,10 @@ struct_declarator_list ...@@ -1320,19 +1215,10 @@ struct_declarator_list
struct_declarator struct_declarator
: identifier { : identifier {
context->checkIsNotReserved(@1, *$1.string); $$ = context->parseStructDeclarator($1.string, @1);
TType* type = new TType(EbtVoid, EbpUndefined);
$$ = new TField(type, $1.string, @1);
} }
| identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
context->checkIsNotReserved(@1, *$1.string); $$ = context->parseStructArrayDeclarator($1.string, @1, $3, @3);
TType* type = new TType(EbtVoid, EbpUndefined);
unsigned int size = context->checkIsValidArraySize(@3, $3);
type->setArraySize(size);
$$ = new TField(type, $1.string, @1);
} }
; ;
...@@ -1364,9 +1250,7 @@ simple_statement ...@@ -1364,9 +1250,7 @@ simple_statement
compound_statement compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; } : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0) { $3->setLine(@$);
$3->setLine(@$);
}
$$ = $3; $$ = $3;
} }
; ;
...@@ -1384,12 +1268,10 @@ statement_with_scope ...@@ -1384,12 +1268,10 @@ statement_with_scope
compound_statement_no_new_scope compound_statement_no_new_scope
// Statement that doesn't create a new scope, for selection_statement, iteration_statement // Statement that doesn't create a new scope, for selection_statement, iteration_statement
: LEFT_BRACE RIGHT_BRACE { : LEFT_BRACE RIGHT_BRACE {
$$ = 0; $$ = nullptr;
} }
| LEFT_BRACE statement_list RIGHT_BRACE { | LEFT_BRACE statement_list RIGHT_BRACE {
if ($2) { $2->setLine(@$);
$2->setLine(@$);
}
$$ = $2; $$ = $2;
} }
; ;
...@@ -1397,7 +1279,6 @@ compound_statement_no_new_scope ...@@ -1397,7 +1279,6 @@ compound_statement_no_new_scope
statement_list statement_list
: statement { : statement {
$$ = new TIntermBlock(); $$ = new TIntermBlock();
$$->setLine(@$);
$$->appendStatement($1); $$->appendStatement($1);
} }
| statement_list statement { | statement_list statement {
...@@ -1408,13 +1289,12 @@ statement_list ...@@ -1408,13 +1289,12 @@ statement_list
expression_statement expression_statement
: SEMICOLON { $$ = 0; } : SEMICOLON { $$ = 0; }
| expression SEMICOLON { $$ = static_cast<TIntermNode*>($1); } | expression SEMICOLON { $$ = $1; }
; ;
selection_statement selection_statement
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
context->checkIsScalarBool(@1, $3); $$ = context->addIfElse($3, $5, @1);
$$ = context->intermediate.addIfElse($3, $5, @1);
} }
; ;
...@@ -1425,7 +1305,7 @@ selection_rest_statement ...@@ -1425,7 +1305,7 @@ selection_rest_statement
} }
| statement_with_scope { | statement_with_scope {
$$.node1 = $1; $$.node1 = $1;
$$.node2 = 0; $$.node2 = nullptr;
} }
; ;
...@@ -1446,7 +1326,6 @@ case_label ...@@ -1446,7 +1326,6 @@ case_label
; ;
condition condition
// In 1996 c++ draft, conditions can include single declarations
: expression { : expression {
$$ = $1; $$ = $1;
context->checkIsScalarBool($1->getLine(), $1); context->checkIsScalarBool($1->getLine(), $1);
...@@ -1463,8 +1342,6 @@ iteration_statement ...@@ -1463,8 +1342,6 @@ iteration_statement
context->decrLoopNestingLevel(); context->decrLoopNestingLevel();
} }
| DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
context->checkIsScalarBool(@8, $6);
$$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); $$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
context->decrLoopNestingLevel(); context->decrLoopNestingLevel();
} }
...@@ -1518,7 +1395,6 @@ jump_statement ...@@ -1518,7 +1395,6 @@ jump_statement
$$ = context->addBranch(EOpReturn, $2, @1); $$ = context->addBranch(EOpReturn, $2, @1);
} }
| DISCARD SEMICOLON { | DISCARD SEMICOLON {
FRAG_ONLY("discard", @1);
$$ = context->addBranch(EOpKill, @1); $$ = context->addBranch(EOpKill, @1);
} }
; ;
......
...@@ -392,49 +392,37 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -392,49 +392,37 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
#define VERTEX_ONLY(S, L) { \ #define VERTEX_ONLY(S, L) { \
if (context->getShaderType() != GL_VERTEX_SHADER) { \ if (context->getShaderType() != GL_VERTEX_SHADER) { \
context->error(L, " supported in vertex shaders only ", S); \ context->error(L, " supported in vertex shaders only", S); \
} \
}
#define FRAG_ONLY(S, L) { \
if (context->getShaderType() != GL_FRAGMENT_SHADER) { \
context->error(L, " supported in fragment shaders only ", S); \
} \ } \
} }
#define COMPUTE_ONLY(S, L) { \ #define COMPUTE_ONLY(S, L) { \
if (context->getShaderType() != GL_COMPUTE_SHADER) { \ if (context->getShaderType() != GL_COMPUTE_SHADER) { \
context->error(L, " supported in compute shaders only ", S); \ context->error(L, " supported in compute shaders only", S); \
} \
}
#define NON_COMPUTE_ONLY(S, L) { \
if (context->getShaderType() != GL_VERTEX_SHADER && context->getShaderType() != GL_FRAGMENT_SHADER) { \
context->error(L, " supported in vertex and fragment shaders only ", S); \
} \ } \
} }
#define ES2_ONLY(S, L) { \ #define ES2_ONLY(S, L) { \
if (context->getShaderVersion() != 100) { \ if (context->getShaderVersion() != 100) { \
context->error(L, " supported in GLSL ES 1.00 only ", S); \ context->error(L, " supported in GLSL ES 1.00 only", S); \
} \ } \
} }
#define ES3_OR_NEWER(TOKEN, LINE, REASON) { \ #define ES3_OR_NEWER(TOKEN, LINE, REASON) { \
if (context->getShaderVersion() < 300) { \ if (context->getShaderVersion() < 300) { \
context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN); \ context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \
} \ } \
} }
#define ES3_OR_NEWER_OR_MULTIVIEW(TOKEN, LINE, REASON) { \ #define ES3_OR_NEWER_OR_MULTIVIEW(TOKEN, LINE, REASON) { \
if (context->getShaderVersion() < 300 && !context->isMultiviewExtensionEnabled()) { \ if (context->getShaderVersion() < 300 && !context->isMultiviewExtensionEnabled()) { \
context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN); \ context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \
} \ } \
} }
#define ES3_1_ONLY(TOKEN, LINE, REASON) { \ #define ES3_1_ONLY(TOKEN, LINE, REASON) { \
if (context->getShaderVersion() != 310) { \ if (context->getShaderVersion() != 310) { \
context->error(LINE, REASON " supported in GLSL ES 3.10 only ", TOKEN); \ context->error(LINE, REASON " supported in GLSL ES 3.10 only", TOKEN); \
} \ } \
} }
...@@ -752,36 +740,36 @@ static const yytype_uint8 yytranslate[] = ...@@ -752,36 +740,36 @@ static const yytype_uint8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] = static const yytype_uint16 yyrline[] =
{ {
0, 256, 256, 257, 260, 270, 273, 278, 283, 288, 0, 244, 244, 245, 248, 258, 261, 266, 271, 276,
293, 301, 307, 310, 313, 316, 319, 322, 328, 335, 281, 289, 295, 298, 301, 304, 307, 310, 316, 323,
341, 345, 353, 356, 362, 366, 373, 378, 385, 393, 329, 333, 341, 344, 350, 354, 361, 366, 373, 381,
399, 405, 414, 417, 420, 423, 433, 434, 435, 436, 384, 387, 393, 396, 399, 402, 409, 410, 411, 412,
444, 445, 448, 451, 458, 459, 462, 468, 469, 473, 420, 421, 424, 427, 434, 435, 438, 444, 445, 449,
480, 481, 484, 487, 490, 496, 497, 500, 506, 507, 456, 457, 460, 463, 466, 472, 473, 476, 482, 483,
514, 515, 522, 523, 530, 531, 537, 538, 544, 545, 490, 491, 498, 499, 506, 507, 513, 514, 520, 521,
551, 552, 558, 559, 566, 567, 568, 569, 573, 574, 527, 528, 534, 535, 541, 542, 543, 544, 548, 549,
575, 579, 583, 587, 591, 598, 601, 607, 614, 621, 550, 554, 558, 562, 566, 573, 576, 582, 589, 596,
624, 627, 636, 640, 644, 648, 652, 659, 666, 669, 599, 602, 606, 610, 614, 618, 622, 629, 636, 639,
676, 684, 704, 714, 722, 747, 751, 755, 759, 766, 646, 654, 671, 681, 684, 690, 694, 698, 702, 709,
773, 776, 780, 784, 789, 794, 801, 805, 809, 813, 716, 719, 723, 727, 732, 737, 744, 748, 752, 756,
818, 823, 830, 834, 840, 843, 849, 853, 860, 866, 761, 766, 773, 777, 783, 786, 792, 796, 803, 809,
870, 874, 877, 880, 889, 895, 903, 906, 926, 945, 813, 817, 820, 823, 832, 837, 841, 844, 847, 850,
952, 956, 960, 963, 966, 969, 972, 975, 983, 990, 853, 857, 860, 863, 866, 869, 872, 875, 882, 889,
993, 996, 1002, 1009, 1012, 1018, 1021, 1024, 1027, 1033, 892, 895, 901, 908, 911, 917, 920, 923, 926, 932,
1036, 1041, 1052, 1055, 1058, 1061, 1064, 1067, 1071, 1075, 935, 940, 951, 954, 957, 960, 963, 966, 970, 974,
1079, 1083, 1087, 1091, 1095, 1099, 1103, 1107, 1111, 1115, 978, 982, 986, 990, 994, 998, 1002, 1006, 1010, 1014,
1119, 1123, 1127, 1131, 1135, 1139, 1143, 1147, 1151, 1157, 1018, 1022, 1026, 1030, 1034, 1038, 1042, 1046, 1050, 1056,
1160, 1163, 1166, 1169, 1172, 1175, 1178, 1181, 1184, 1187, 1059, 1062, 1065, 1068, 1071, 1074, 1077, 1080, 1083, 1086,
1190, 1193, 1196, 1199, 1202, 1205, 1208, 1211, 1218, 1224, 1089, 1092, 1095, 1098, 1101, 1104, 1107, 1110, 1117, 1123,
1230, 1233, 1236, 1239, 1242, 1245, 1248, 1251, 1254, 1257, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, 1156,
1260, 1263, 1266, 1269, 1272, 1284, 1284, 1287, 1287, 1293, 1159, 1162, 1165, 1168, 1171, 1179, 1179, 1182, 1182, 1188,
1296, 1302, 1305, 1312, 1316, 1322, 1328, 1340, 1344, 1348, 1191, 1197, 1200, 1207, 1211, 1217, 1220, 1226, 1230, 1234,
1349, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1365, 1366, 1235, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1251, 1252,
1366, 1366, 1375, 1376, 1380, 1380, 1381, 1381, 1386, 1389, 1252, 1252, 1259, 1260, 1264, 1264, 1265, 1265, 1270, 1273,
1398, 1403, 1410, 1411, 1415, 1422, 1426, 1433, 1433, 1440, 1280, 1284, 1291, 1292, 1296, 1302, 1306, 1313, 1313, 1320,
1443, 1450, 1454, 1460, 1460, 1465, 1465, 1471, 1471, 1479, 1323, 1329, 1333, 1339, 1339, 1344, 1344, 1348, 1348, 1356,
1482, 1488, 1491, 1497, 1501, 1508, 1511, 1514, 1517, 1520, 1359, 1365, 1368, 1374, 1378, 1385, 1388, 1391, 1394, 1397,
1529, 1535, 1541, 1544, 1550, 1550 1405, 1411, 1417, 1420, 1426, 1426
}; };
#endif #endif
...@@ -2759,9 +2747,6 @@ yyreduce: ...@@ -2759,9 +2747,6 @@ yyreduce:
case 29: case 29:
{ {
if ((yyvsp[0].interm.type).array) {
ES3_OR_NEWER("[]", (yylsp[0]), "array constructor");
}
(yyval.interm.function) = context->addConstructorFunc((yyvsp[0].interm.type)); (yyval.interm.function) = context->addConstructorFunc((yyvsp[0].interm.type));
} }
...@@ -2770,10 +2755,7 @@ yyreduce: ...@@ -2770,10 +2755,7 @@ yyreduce:
case 30: case 30:
{ {
context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); (yyval.interm.function) = context->addNonConstructorFunc((yyvsp[0].lex).string, (yylsp[0]));
const TType *type = TCache::getType(EbtVoid, EbpUndefined);
TFunction *function = new TFunction((yyvsp[0].lex).string, type);
(yyval.interm.function) = function;
} }
break; break;
...@@ -2781,10 +2763,7 @@ yyreduce: ...@@ -2781,10 +2763,7 @@ yyreduce:
case 31: case 31:
{ {
context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); (yyval.interm.function) = context->addNonConstructorFunc((yyvsp[0].lex).string, (yylsp[0]));
const TType *type = TCache::getType(EbtVoid, EbpUndefined);
TFunction *function = new TFunction((yyvsp[0].lex).string, type);
(yyval.interm.function) = function;
} }
break; break;
...@@ -2816,29 +2795,26 @@ yyreduce: ...@@ -2816,29 +2795,26 @@ yyreduce:
case 35: case 35:
{ {
if ((yyvsp[-1].interm).op != EOpNull) { (yyval.interm.intermTypedNode) = context->addUnaryMath((yyvsp[-1].interm.op), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
(yyval.interm.intermTypedNode) = context->addUnaryMath((yyvsp[-1].interm).op, (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
} else
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
} }
break; break;
case 36: case 36:
{ (yyval.interm).op = EOpPositive; } { (yyval.interm.op) = EOpPositive; }
break; break;
case 37: case 37:
{ (yyval.interm).op = EOpNegative; } { (yyval.interm.op) = EOpNegative; }
break; break;
case 38: case 38:
{ (yyval.interm).op = EOpLogicalNot; } { (yyval.interm.op) = EOpLogicalNot; }
break; break;
...@@ -2846,7 +2822,7 @@ yyreduce: ...@@ -2846,7 +2822,7 @@ yyreduce:
{ {
ES3_OR_NEWER("~", (yyloc), "bit-wise operator"); ES3_OR_NEWER("~", (yyloc), "bit-wise operator");
(yyval.interm).op = EOpBitwiseNot; (yyval.interm.op) = EOpBitwiseNot;
} }
break; break;
...@@ -3098,27 +3074,26 @@ yyreduce: ...@@ -3098,27 +3074,26 @@ yyreduce:
case 73: case 73:
{ {
context->checkCanBeLValue((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = context->addAssign((yyvsp[-1].interm.op), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
(yyval.interm.intermTypedNode) = context->addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
} }
break; break;
case 74: case 74:
{ (yyval.interm).op = EOpAssign; } { (yyval.interm.op) = EOpAssign; }
break; break;
case 75: case 75:
{ (yyval.interm).op = EOpMulAssign; } { (yyval.interm.op) = EOpMulAssign; }
break; break;
case 76: case 76:
{ (yyval.interm).op = EOpDivAssign; } { (yyval.interm.op) = EOpDivAssign; }
break; break;
...@@ -3126,20 +3101,20 @@ yyreduce: ...@@ -3126,20 +3101,20 @@ yyreduce:
{ {
ES3_OR_NEWER("%=", (yyloc), "integer modulus operator"); ES3_OR_NEWER("%=", (yyloc), "integer modulus operator");
(yyval.interm).op = EOpIModAssign; (yyval.interm.op) = EOpIModAssign;
} }
break; break;
case 78: case 78:
{ (yyval.interm).op = EOpAddAssign; } { (yyval.interm.op) = EOpAddAssign; }
break; break;
case 79: case 79:
{ (yyval.interm).op = EOpSubAssign; } { (yyval.interm.op) = EOpSubAssign; }
break; break;
...@@ -3147,7 +3122,7 @@ yyreduce: ...@@ -3147,7 +3122,7 @@ yyreduce:
{ {
ES3_OR_NEWER("<<=", (yyloc), "bit-wise operator"); ES3_OR_NEWER("<<=", (yyloc), "bit-wise operator");
(yyval.interm).op = EOpBitShiftLeftAssign; (yyval.interm.op) = EOpBitShiftLeftAssign;
} }
break; break;
...@@ -3156,7 +3131,7 @@ yyreduce: ...@@ -3156,7 +3131,7 @@ yyreduce:
{ {
ES3_OR_NEWER(">>=", (yyloc), "bit-wise operator"); ES3_OR_NEWER(">>=", (yyloc), "bit-wise operator");
(yyval.interm).op = EOpBitShiftRightAssign; (yyval.interm.op) = EOpBitShiftRightAssign;
} }
break; break;
...@@ -3165,7 +3140,7 @@ yyreduce: ...@@ -3165,7 +3140,7 @@ yyreduce:
{ {
ES3_OR_NEWER("&=", (yyloc), "bit-wise operator"); ES3_OR_NEWER("&=", (yyloc), "bit-wise operator");
(yyval.interm).op = EOpBitwiseAndAssign; (yyval.interm.op) = EOpBitwiseAndAssign;
} }
break; break;
...@@ -3174,7 +3149,7 @@ yyreduce: ...@@ -3174,7 +3149,7 @@ yyreduce:
{ {
ES3_OR_NEWER("^=", (yyloc), "bit-wise operator"); ES3_OR_NEWER("^=", (yyloc), "bit-wise operator");
(yyval.interm).op = EOpBitwiseXorAssign; (yyval.interm.op) = EOpBitwiseXorAssign;
} }
break; break;
...@@ -3183,7 +3158,7 @@ yyreduce: ...@@ -3183,7 +3158,7 @@ yyreduce:
{ {
ES3_OR_NEWER("|=", (yyloc), "bit-wise operator"); ES3_OR_NEWER("|=", (yyloc), "bit-wise operator");
(yyval.interm).op = EOpBitwiseOrAssign; (yyval.interm.op) = EOpBitwiseOrAssign;
} }
break; break;
...@@ -3241,13 +3216,8 @@ yyreduce: ...@@ -3241,13 +3216,8 @@ yyreduce:
case 91: case 91:
{ {
if (((yyvsp[-2].interm.precision) == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->parseDefaultPrecisionQualifier((yyvsp[-2].interm.precision), (yyvsp[-1].interm.type), (yylsp[-3]));
context->error((yylsp[-3]), "precision is not supported in fragment shader", "highp"); (yyval.interm.intermNode) = nullptr;
}
if (!context->symbolTable.setDefaultPrecision( (yyvsp[-1].interm.type), (yyvsp[-2].interm.precision) )) {
context->error((yylsp[-3]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[-1].interm.type).getBasicType()));
}
(yyval.interm.intermNode) = 0;
} }
break; break;
...@@ -3283,7 +3253,7 @@ yyreduce: ...@@ -3283,7 +3253,7 @@ yyreduce:
{ {
context->parseGlobalLayoutQualifier(*(yyvsp[-1].interm.typeQualifierBuilder)); context->parseGlobalLayoutQualifier(*(yyvsp[-1].interm.typeQualifierBuilder));
(yyval.interm.intermNode) = 0; (yyval.interm.intermNode) = nullptr;
} }
break; break;
...@@ -3326,10 +3296,10 @@ yyreduce: ...@@ -3326,10 +3296,10 @@ yyreduce:
{ {
// Add the parameter // Add the parameter
(yyval.interm.function) = (yyvsp[-1].interm.function); (yyval.interm.function) = (yyvsp[-1].interm.function);
if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) if ((yyvsp[0].interm.param).type->getBasicType() != EbtVoid)
(yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param.turnToConst()); {
else (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm.param).turnToConst());
delete (yyvsp[0].interm).param.type; }
} }
break; break;
...@@ -3337,20 +3307,17 @@ yyreduce: ...@@ -3337,20 +3307,17 @@ yyreduce:
case 101: case 101:
{ {
// (yyval.interm.function) = (yyvsp[-2].interm.function);
// Only first parameter of one-parameter functions can be void // Only first parameter of one-parameter functions can be void
// The check for named parameters not being void is done in parameter_declarator // The check for named parameters not being void is done in parameter_declarator
// if ((yyvsp[0].interm.param).type->getBasicType() == EbtVoid)
if ((yyvsp[0].interm).param.type->getBasicType() == EbtVoid) { {
//
// This parameter > first is void // This parameter > first is void
// context->error((yylsp[-1]), "cannot be a parameter type except for '(void)'", "void");
context->error((yylsp[-1]), "cannot be an argument type except for '(void)'", "void"); }
delete (yyvsp[0].interm).param.type; else
} else { {
// Add the parameter (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm.param).turnToConst());
(yyval.interm.function) = (yyvsp[-2].interm.function);
(yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param.turnToConst());
} }
} }
...@@ -3370,12 +3337,7 @@ yyreduce: ...@@ -3370,12 +3337,7 @@ yyreduce:
case 103: case 103:
{ {
if ((yyvsp[-1].interm.type).getBasicType() == EbtVoid) { (yyval.interm.param) = context->parseParameterDeclarator((yyvsp[-1].interm.type), (yyvsp[0].lex).string, (yylsp[0]));
context->error((yylsp[0]), "illegal use of type 'void'", (yyvsp[0].lex).string->c_str());
}
context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string);
TParameter param = {(yyvsp[0].lex).string, new TType((yyvsp[-1].interm.type))};
(yyval.interm).param = param;
} }
break; break;
...@@ -3383,18 +3345,7 @@ yyreduce: ...@@ -3383,18 +3345,7 @@ yyreduce:
case 104: case 104:
{ {
// Check that we can make an array out of this type (yyval.interm.param) = context->parseParameterArrayDeclarator((yyvsp[-3].lex).string, (yylsp[-3]), (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]), &(yyvsp[-4].interm.type));
context->checkIsValidTypeForArray((yylsp[-2]), (yyvsp[-4].interm.type));
context->checkIsNotReserved((yylsp[-3]), *(yyvsp[-3].lex).string);
unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
(yyvsp[-4].interm.type).setArraySize(size);
TType* type = new TType((yyvsp[-4].interm.type));
TParameter param = { (yyvsp[-3].lex).string, type };
(yyval.interm).param = param;
} }
break; break;
...@@ -3402,8 +3353,8 @@ yyreduce: ...@@ -3402,8 +3353,8 @@ yyreduce:
case 105: case 105:
{ {
(yyval.interm) = (yyvsp[0].interm); (yyval.interm.param) = (yyvsp[0].interm.param);
context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm).param.type); context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.param).type);
} }
break; break;
...@@ -3411,8 +3362,8 @@ yyreduce: ...@@ -3411,8 +3362,8 @@ yyreduce:
case 106: case 106:
{ {
(yyval.interm) = (yyvsp[0].interm); (yyval.interm.param) = (yyvsp[0].interm.param);
(yyval.interm).param.type->setQualifier(EvqIn); (yyval.interm.param).type->setQualifier(EvqIn);
} }
break; break;
...@@ -3420,8 +3371,8 @@ yyreduce: ...@@ -3420,8 +3371,8 @@ yyreduce:
case 107: case 107:
{ {
(yyval.interm) = (yyvsp[0].interm); (yyval.interm.param) = (yyvsp[0].interm.param);
context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm).param.type); context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.param).type);
} }
break; break;
...@@ -3429,8 +3380,8 @@ yyreduce: ...@@ -3429,8 +3380,8 @@ yyreduce:
case 108: case 108:
{ {
(yyval.interm) = (yyvsp[0].interm); (yyval.interm.param) = (yyvsp[0].interm.param);
(yyval.interm).param.type->setQualifier(EvqIn); (yyval.interm.param).type->setQualifier(EvqIn);
} }
break; break;
...@@ -3439,7 +3390,7 @@ yyreduce: ...@@ -3439,7 +3390,7 @@ yyreduce:
{ {
TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; TParameter param = { 0, new TType((yyvsp[0].interm.type)) };
(yyval.interm).param = param; (yyval.interm.param) = param;
} }
break; break;
...@@ -3662,8 +3613,7 @@ yyreduce: ...@@ -3662,8 +3613,7 @@ yyreduce:
{ {
VERTEX_ONLY("attribute", (yylsp[0])); VERTEX_ONLY("attribute", (yylsp[0]));
ES2_ONLY("attribute", (yylsp[0])); ES2_ONLY("attribute", (yylsp[0]));
context->checkIsAtGlobalLevel((yylsp[0]), "attribute"); (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqAttribute, (yylsp[0]));
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqAttribute, (yylsp[0]));
} }
break; break;
...@@ -3672,11 +3622,7 @@ yyreduce: ...@@ -3672,11 +3622,7 @@ yyreduce:
{ {
ES2_ONLY("varying", (yylsp[0])); ES2_ONLY("varying", (yylsp[0]));
context->checkIsAtGlobalLevel((yylsp[0]), "varying"); (yyval.interm.qualifierWrapper) = context->parseVaryingQualifier((yylsp[0]));
if (context->getShaderType() == GL_VERTEX_SHADER)
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVaryingOut, (yylsp[0]));
else
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVaryingIn, (yylsp[0]));
} }
break; break;
...@@ -3692,24 +3638,7 @@ yyreduce: ...@@ -3692,24 +3638,7 @@ yyreduce:
case 137: case 137:
{ {
if (context->declaringFunction()) (yyval.interm.qualifierWrapper) = context->parseInQualifier((yylsp[0]));
{
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqIn, (yylsp[0]));
}
else if (context->getShaderType() == GL_FRAGMENT_SHADER)
{
ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier");
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqFragmentIn, (yylsp[0]));
}
else if (context->getShaderType() == GL_VERTEX_SHADER)
{
ES3_OR_NEWER_OR_MULTIVIEW("in", (yylsp[0]), "storage qualifier");
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVertexIn, (yylsp[0]));
}
else
{
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqComputeIn, (yylsp[0]));
}
} }
break; break;
...@@ -3717,23 +3646,7 @@ yyreduce: ...@@ -3717,23 +3646,7 @@ yyreduce:
case 138: case 138:
{ {
if (context->declaringFunction()) (yyval.interm.qualifierWrapper) = context->parseOutQualifier((yylsp[0]));
{
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqOut, (yylsp[0]));
}
else
{
ES3_OR_NEWER("out", (yylsp[0]), "storage qualifier");
NON_COMPUTE_ONLY("out", (yylsp[0]));
if (context->getShaderType() == GL_FRAGMENT_SHADER)
{
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqFragmentOut, (yylsp[0]));
}
else
{
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqVertexOut, (yylsp[0]));
}
}
} }
break; break;
...@@ -3741,11 +3654,7 @@ yyreduce: ...@@ -3741,11 +3654,7 @@ yyreduce:
case 139: case 139:
{ {
if (!context->declaringFunction()) (yyval.interm.qualifierWrapper) = context->parseInOutQualifier((yylsp[0]));
{
context->error((yylsp[0]), "invalid qualifier: can be only used with function parameters", "inout");
}
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqInOut, (yylsp[0]));
} }
break; break;
...@@ -3762,8 +3671,7 @@ yyreduce: ...@@ -3762,8 +3671,7 @@ yyreduce:
case 141: case 141:
{ {
context->checkIsAtGlobalLevel((yylsp[0]), "uniform"); (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqUniform, (yylsp[0]));
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqUniform, (yylsp[0]));
} }
break; break;
...@@ -3811,9 +3719,8 @@ yyreduce: ...@@ -3811,9 +3719,8 @@ yyreduce:
case 147: case 147:
{ {
context->checkIsAtGlobalLevel((yylsp[0]), "shared");
COMPUTE_ONLY("shared", (yylsp[0])); COMPUTE_ONLY("shared", (yylsp[0]));
(yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqShared, (yylsp[0])); (yyval.interm.qualifierWrapper) = context->parseGlobalStorageQualifier(EvqShared, (yylsp[0]));
} }
break; break;
...@@ -4472,13 +4379,9 @@ yyreduce: ...@@ -4472,13 +4379,9 @@ yyreduce:
case 224: case 224:
{ {
// // This is for user defined type names. The lexical phase looked up the type.
// This is for user defined type names. The lexical phase looked up the
// type.
//
TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType(); TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType();
(yyval.interm.typeSpecifierNonArray).initialize(EbtStruct, (yylsp[0])); (yyval.interm.typeSpecifierNonArray).initializeStruct(&structure, false, (yylsp[0]));
(yyval.interm.typeSpecifierNonArray).userDef = &structure;
} }
break; break;
...@@ -4564,10 +4467,7 @@ yyreduce: ...@@ -4564,10 +4467,7 @@ yyreduce:
case 235: case 235:
{ {
context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); (yyval.interm.field) = context->parseStructDeclarator((yyvsp[0].lex).string, (yylsp[0]));
TType* type = new TType(EbtVoid, EbpUndefined);
(yyval.interm.field) = new TField(type, (yyvsp[0].lex).string, (yylsp[0]));
} }
break; break;
...@@ -4575,13 +4475,7 @@ yyreduce: ...@@ -4575,13 +4475,7 @@ yyreduce:
case 236: case 236:
{ {
context->checkIsNotReserved((yylsp[-3]), *(yyvsp[-3].lex).string); (yyval.interm.field) = context->parseStructArrayDeclarator((yyvsp[-3].lex).string, (yylsp[-3]), (yyvsp[-1].interm.intermTypedNode), (yylsp[-1]));
TType* type = new TType(EbtVoid, EbpUndefined);
unsigned int size = context->checkIsValidArraySize((yylsp[-1]), (yyvsp[-1].interm.intermTypedNode));
type->setArraySize(size);
(yyval.interm.field) = new TField(type, (yyvsp[-3].lex).string, (yylsp[-3]));
} }
break; break;
...@@ -4673,9 +4567,7 @@ yyreduce: ...@@ -4673,9 +4567,7 @@ yyreduce:
case 251: case 251:
{ {
if ((yyvsp[-2].interm.intermBlock) != 0) { (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
(yyvsp[-2].interm.intermBlock)->setLine((yyloc));
}
(yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock); (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
} }
...@@ -4720,7 +4612,7 @@ yyreduce: ...@@ -4720,7 +4612,7 @@ yyreduce:
case 258: case 258:
{ {
(yyval.interm.intermBlock) = 0; (yyval.interm.intermBlock) = nullptr;
} }
break; break;
...@@ -4728,9 +4620,7 @@ yyreduce: ...@@ -4728,9 +4620,7 @@ yyreduce:
case 259: case 259:
{ {
if ((yyvsp[-1].interm.intermBlock)) { (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
(yyvsp[-1].interm.intermBlock)->setLine((yyloc));
}
(yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock); (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
} }
...@@ -4740,7 +4630,6 @@ yyreduce: ...@@ -4740,7 +4630,6 @@ yyreduce:
{ {
(yyval.interm.intermBlock) = new TIntermBlock(); (yyval.interm.intermBlock) = new TIntermBlock();
(yyval.interm.intermBlock)->setLine((yyloc));
(yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode)); (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
} }
...@@ -4763,15 +4652,14 @@ yyreduce: ...@@ -4763,15 +4652,14 @@ yyreduce:
case 263: case 263:
{ (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[-1].interm.intermTypedNode)); } { (yyval.interm.intermNode) = (yyvsp[-1].interm.intermTypedNode); }
break; break;
case 264: case 264:
{ {
context->checkIsScalarBool((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = context->addIfElse((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
(yyval.interm.intermNode) = context->intermediate.addIfElse((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4]));
} }
break; break;
...@@ -4789,7 +4677,7 @@ yyreduce: ...@@ -4789,7 +4677,7 @@ yyreduce:
{ {
(yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
(yyval.interm.nodePair).node2 = 0; (yyval.interm.nodePair).node2 = nullptr;
} }
break; break;
...@@ -4867,8 +4755,6 @@ yyreduce: ...@@ -4867,8 +4755,6 @@ yyreduce:
case 276: case 276:
{ {
context->checkIsScalarBool((yylsp[0]), (yyvsp[-2].interm.intermTypedNode));
(yyval.interm.intermNode) = context->addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[-5].interm.intermNode), (yylsp[-4])); (yyval.interm.intermNode) = context->addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[-5].interm.intermNode), (yylsp[-4]));
context->decrLoopNestingLevel(); context->decrLoopNestingLevel();
} }
...@@ -4976,7 +4862,6 @@ yyreduce: ...@@ -4976,7 +4862,6 @@ yyreduce:
case 289: case 289:
{ {
FRAG_ONLY("discard", (yylsp[-1]));
(yyval.interm.intermNode) = context->addBranch(EOpKill, (yylsp[-1])); (yyval.interm.intermNode) = context->addBranch(EOpKill, (yylsp[-1]));
} }
......
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