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