Implement write-only semantic checking, the non-r32f/i/u readonly/writeonly check, and ES 3.1 support of volatile. Also, fix a typo in MaxComputeGroupY.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27765 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
bd2d8fb004
commit
da66bc7d29
10 changed files with 595 additions and 154 deletions
|
|
@ -187,10 +187,8 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT
|
|||
//
|
||||
// Returns the added node.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc loc)
|
||||
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc)
|
||||
{
|
||||
TIntermTyped* child = childNode->getAsTyped();
|
||||
|
||||
if (child->getType().getBasicType() == EbtBlock)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -678,6 +678,34 @@ void TParseContext::checkIoArrayConsistency(TSourceLoc loc, int requiredSize, co
|
|||
}
|
||||
}
|
||||
|
||||
// Handle seeing a binary node with a math operation.
|
||||
TIntermTyped* TParseContext::handleBinaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
|
||||
{
|
||||
rValueErrorCheck(loc, str, left->getAsTyped());
|
||||
rValueErrorCheck(loc, str, right->getAsTyped());
|
||||
|
||||
TIntermTyped* result = intermediate.addBinaryMath(op, left, right, loc);
|
||||
if (! result)
|
||||
binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Handle seeing a unary node with a math operation.
|
||||
TIntermTyped* TParseContext::handleUnaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* childNode)
|
||||
{
|
||||
rValueErrorCheck(loc, str, childNode);
|
||||
|
||||
TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc);
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
else
|
||||
unaryOpError(loc, str, childNode->getCompleteString());
|
||||
|
||||
return childNode;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle seeing a base.field dereference in the grammar.
|
||||
//
|
||||
|
|
@ -1540,7 +1568,6 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
|
|||
//
|
||||
bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
|
||||
{
|
||||
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||
|
||||
if (binaryNode) {
|
||||
|
|
@ -1582,6 +1609,7 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
|
|||
|
||||
|
||||
const char* symbol = 0;
|
||||
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||
if (symNode != 0)
|
||||
symbol = symNode->getName().c_str();
|
||||
|
||||
|
|
@ -1644,6 +1672,32 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
|
|||
return true;
|
||||
}
|
||||
|
||||
// Test for and give an error if the node can't be read from.
|
||||
void TParseContext::rValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node)
|
||||
{
|
||||
if (! node)
|
||||
return;
|
||||
|
||||
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||
if (binaryNode) {
|
||||
switch(binaryNode->getOp()) {
|
||||
case EOpIndexDirect:
|
||||
case EOpIndexIndirect:
|
||||
case EOpIndexDirectStruct:
|
||||
case EOpVectorSwizzle:
|
||||
rValueErrorCheck(loc, op, binaryNode->getLeft());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||
if (symNode && symNode->getQualifier().writeonly)
|
||||
error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
|
||||
}
|
||||
|
||||
//
|
||||
// Both test, and if necessary spit out an error, to see if the node is really
|
||||
// a constant.
|
||||
|
|
@ -3530,6 +3584,15 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
|
|||
error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
|
||||
if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard)
|
||||
error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
|
||||
|
||||
if (profile == EEsProfile) {
|
||||
// "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must
|
||||
// specify either memory qualifier readonly or the memory qualifier writeonly."
|
||||
if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) {
|
||||
if (! qualifier.readonly && ! qualifier.writeonly)
|
||||
error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type.isImage() && ! qualifier.writeonly)
|
||||
error(loc, "image variables not declared 'writeonly' must have a format layout qualifier", "", "");
|
||||
|
|
@ -3828,7 +3891,9 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
|||
if (voidErrorCheck(loc, identifier, type.getBasicType()))
|
||||
return 0;
|
||||
|
||||
if (! initializer)
|
||||
if (initializer)
|
||||
rValueErrorCheck(loc, "initializer", initializer);
|
||||
else
|
||||
nonInitConstCheck(loc, identifier, type);
|
||||
|
||||
invariantCheck(loc, type, identifier);
|
||||
|
|
@ -4118,8 +4183,9 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
|
|||
//
|
||||
TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, const TType& type, TOperator op)
|
||||
{
|
||||
if (node == 0)
|
||||
if (node == 0 || node->getAsTyped() == 0)
|
||||
return 0;
|
||||
rValueErrorCheck(loc, "constructor", node->getAsTyped());
|
||||
|
||||
TIntermAggregate* aggrNode = node->getAsAggregate();
|
||||
|
||||
|
|
@ -4150,7 +4216,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||
else if (op == EOpConstructStruct)
|
||||
newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc());
|
||||
else
|
||||
newNode = constructBuiltIn(type, op, node, node->getLoc(), false);
|
||||
newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
|
||||
|
||||
if (newNode && (type.isArray() || op == EOpConstructStruct))
|
||||
newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
|
||||
|
|
@ -4178,7 +4244,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||
else if (op == EOpConstructStruct)
|
||||
newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc());
|
||||
else
|
||||
newNode = constructBuiltIn(type, op, *p, node->getLoc(), true);
|
||||
newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
|
||||
|
||||
if (newNode)
|
||||
*p = newNode;
|
||||
|
|
@ -4198,7 +4264,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||
//
|
||||
// Returns 0 for an error or the constructed node.
|
||||
//
|
||||
TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermNode* node, TSourceLoc loc, bool subset)
|
||||
TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, TSourceLoc loc, bool subset)
|
||||
{
|
||||
TIntermTyped* newNode;
|
||||
TOperator basicOp;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ public:
|
|||
int getIoArrayImplicitSize() const;
|
||||
void checkIoArrayConsistency(TSourceLoc, int requiredSize, const char* feature, TType&, const TString&);
|
||||
|
||||
TIntermTyped* handleBinaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||
TIntermTyped* handleUnaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* childNode);
|
||||
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
|
||||
TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype);
|
||||
TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
|
||||
|
|
@ -111,6 +113,7 @@ public:
|
|||
void binaryOpError(TSourceLoc, const char* op, TString left, TString right);
|
||||
void variableCheck(TIntermTyped*& nodePtr);
|
||||
bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
|
||||
void rValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
|
||||
void constantValueCheck(TIntermTyped* node, const char* token);
|
||||
void integerCheck(const TIntermTyped* node, const char* token);
|
||||
void globalCheck(TSourceLoc, const char* token);
|
||||
|
|
@ -170,7 +173,7 @@ public:
|
|||
TIntermNode* declareVariable(TSourceLoc, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||
TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator);
|
||||
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
|
||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
|
||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, TSourceLoc, bool subset);
|
||||
void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
||||
void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||
void fixBlockXfbOffsets(TSourceLoc, TQualifier&, TTypeList&);
|
||||
|
|
|
|||
|
|
@ -677,8 +677,7 @@ int TScanContext::tokenizeIdentifier()
|
|||
if (parseContext.profile == EEsProfile && parseContext.version >= 310 ||
|
||||
parseContext.extensionsTurnedOn(1, &GL_ARB_shader_atomic_counters))
|
||||
return keyword;
|
||||
else
|
||||
return es30ReservedFromGLSL(420);
|
||||
return es30ReservedFromGLSL(420);
|
||||
|
||||
case COHERENT:
|
||||
case RESTRICT:
|
||||
|
|
@ -686,10 +685,11 @@ int TScanContext::tokenizeIdentifier()
|
|||
case WRITEONLY:
|
||||
if (parseContext.profile == EEsProfile && parseContext.version >= 310)
|
||||
return keyword;
|
||||
else
|
||||
return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420);
|
||||
return es30ReservedFromGLSL(parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store) ? 130 : 420);
|
||||
|
||||
case VOLATILE:
|
||||
if (parseContext.profile == EEsProfile && parseContext.version >= 310)
|
||||
return keyword;
|
||||
if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || (parseContext.version < 420 && ! parseContext.extensionsTurnedOn(1, &GL_ARB_shader_image_load_store))))
|
||||
reservedWord();
|
||||
return keyword;
|
||||
|
|
|
|||
|
|
@ -265,20 +265,12 @@ postfix_expression
|
|||
| postfix_expression INC_OP {
|
||||
parseContext.variableCheck($1);
|
||||
parseContext.lValueErrorCheck($2.loc, "++", $1);
|
||||
$$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.unaryOpError($2.loc, "++", $1->getCompleteString());
|
||||
$$ = $1;
|
||||
}
|
||||
$$ = parseContext.handleUnaryMath($2.loc, "++", EOpPostIncrement, $1);
|
||||
}
|
||||
| postfix_expression DEC_OP {
|
||||
parseContext.variableCheck($1);
|
||||
parseContext.lValueErrorCheck($2.loc, "--", $1);
|
||||
$$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.unaryOpError($2.loc, "--", $1->getCompleteString());
|
||||
$$ = $1;
|
||||
}
|
||||
$$ = parseContext.handleUnaryMath($2.loc, "--", EOpPostDecrement, $1);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -391,34 +383,22 @@ unary_expression
|
|||
}
|
||||
| INC_OP unary_expression {
|
||||
parseContext.lValueErrorCheck($1.loc, "++", $2);
|
||||
$$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.unaryOpError($1.loc, "++", $2->getCompleteString());
|
||||
$$ = $2;
|
||||
}
|
||||
$$ = parseContext.handleUnaryMath($1.loc, "++", EOpPreIncrement, $2);
|
||||
}
|
||||
| DEC_OP unary_expression {
|
||||
parseContext.lValueErrorCheck($1.loc, "--", $2);
|
||||
$$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.unaryOpError($1.loc, "--", $2->getCompleteString());
|
||||
$$ = $2;
|
||||
}
|
||||
$$ = parseContext.handleUnaryMath($1.loc, "--", EOpPreDecrement, $2);
|
||||
}
|
||||
| unary_operator unary_expression {
|
||||
if ($1.op != EOpNull) {
|
||||
$$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.loc);
|
||||
if ($$ == 0) {
|
||||
char errorOp[2] = {0, 0};
|
||||
switch($1.op) {
|
||||
case EOpNegative: errorOp[0] = '-'; break;
|
||||
case EOpLogicalNot: errorOp[0] = '!'; break;
|
||||
case EOpBitwiseNot: errorOp[0] = '~'; break;
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
parseContext.unaryOpError($1.loc, errorOp, $2->getCompleteString());
|
||||
$$ = $2;
|
||||
char errorOp[2] = {0, 0};
|
||||
switch($1.op) {
|
||||
case EOpNegative: errorOp[0] = '-'; break;
|
||||
case EOpLogicalNot: errorOp[0] = '!'; break;
|
||||
case EOpBitwiseNot: errorOp[0] = '~'; break;
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
$$ = parseContext.handleUnaryMath($1.loc, errorOp, $1.op, $2);
|
||||
} else {
|
||||
$$ = $2;
|
||||
if ($$->getAsConstantUnion())
|
||||
|
|
@ -440,44 +420,34 @@ unary_operator
|
|||
multiplicative_expression
|
||||
: unary_expression { $$ = $1; }
|
||||
| multiplicative_expression STAR unary_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "*", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "*", EOpMul, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
| multiplicative_expression SLASH unary_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "/", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "/", EOpDiv, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
| multiplicative_expression PERCENT unary_expression {
|
||||
parseContext.fullIntegerCheck($2.loc, "%");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "%", EOpMod, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
additive_expression
|
||||
: multiplicative_expression { $$ = $1; }
|
||||
| additive_expression PLUS multiplicative_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "+", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "+", EOpAdd, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
| additive_expression DASH multiplicative_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "-", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "-", EOpSub, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -485,51 +455,39 @@ shift_expression
|
|||
: additive_expression { $$ = $1; }
|
||||
| shift_expression LEFT_OP additive_expression {
|
||||
parseContext.fullIntegerCheck($2.loc, "bit shift left");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "<<", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "<<", EOpLeftShift, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
| shift_expression RIGHT_OP additive_expression {
|
||||
parseContext.fullIntegerCheck($2.loc, "bit shift right");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, ">>", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, ">>", EOpRightShift, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
relational_expression
|
||||
: shift_expression { $$ = $1; }
|
||||
| relational_expression LEFT_ANGLE shift_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "<", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "<", EOpLessThan, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
| relational_expression RIGHT_ANGLE shift_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, ">", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, ">", EOpGreaterThan, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
| relational_expression LE_OP shift_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "<=", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "<=", EOpLessThanEqual, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
| relational_expression GE_OP shift_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, ">=", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, ">=", EOpGreaterThanEqual, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -538,20 +496,16 @@ equality_expression
|
|||
| equality_expression EQ_OP relational_expression {
|
||||
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");
|
||||
parseContext.opaqueCheck($2.loc, $1->getType(), "==");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "==", EOpEqual, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
| equality_expression NE_OP relational_expression {
|
||||
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison");
|
||||
parseContext.opaqueCheck($2.loc, $1->getType(), "!=");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "!=", EOpNotEqual, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -559,11 +513,9 @@ and_expression
|
|||
: equality_expression { $$ = $1; }
|
||||
| and_expression AMPERSAND equality_expression {
|
||||
parseContext.fullIntegerCheck($2.loc, "bitwise and");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "&", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "&", EOpAnd, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -571,11 +523,9 @@ exclusive_or_expression
|
|||
: and_expression { $$ = $1; }
|
||||
| exclusive_or_expression CARET and_expression {
|
||||
parseContext.fullIntegerCheck($2.loc, "bitwise exclusive or");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "^", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "^", EOpExclusiveOr, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -583,44 +533,36 @@ inclusive_or_expression
|
|||
: exclusive_or_expression { $$ = $1; }
|
||||
| inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
|
||||
parseContext.fullIntegerCheck($2.loc, "bitwise inclusive or");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "|", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "|", EOpInclusiveOr, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
logical_and_expression
|
||||
: inclusive_or_expression { $$ = $1; }
|
||||
| logical_and_expression AND_OP inclusive_or_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "&&", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "&&", EOpLogicalAnd, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
logical_xor_expression
|
||||
: logical_and_expression { $$ = $1; }
|
||||
| logical_xor_expression XOR_OP logical_and_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "^^", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "^^", EOpLogicalXor, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
logical_or_expression
|
||||
: logical_xor_expression { $$ = $1; }
|
||||
| logical_or_expression OR_OP logical_xor_expression {
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, "||", $1->getCompleteString(), $3->getCompleteString());
|
||||
$$ = parseContext.handleBinaryMath($2.loc, "||", EOpLogicalOr, $1, $3);
|
||||
if ($$ == 0)
|
||||
$$ = parseContext.intermediate.addConstantUnion(false, $2.loc);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -628,7 +570,9 @@ conditional_expression
|
|||
: logical_or_expression { $$ = $1; }
|
||||
| logical_or_expression QUESTION expression COLON assignment_expression {
|
||||
parseContext.boolCheck($2.loc, $1);
|
||||
|
||||
parseContext.rValueErrorCheck($2.loc, "?", $1);
|
||||
parseContext.rValueErrorCheck($4.loc, ":", $3);
|
||||
parseContext.rValueErrorCheck($4.loc, ":", $5);
|
||||
$$ = parseContext.intermediate.addSelection($1, $3, $5, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.loc, ":", $3->getCompleteString(), $5->getCompleteString());
|
||||
|
|
@ -643,6 +587,7 @@ assignment_expression
|
|||
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment");
|
||||
parseContext.opaqueCheck($2.loc, $1->getType(), "=");
|
||||
parseContext.lValueErrorCheck($2.loc, "assign", $1);
|
||||
parseContext.rValueErrorCheck($2.loc, "assign", $3);
|
||||
$$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc);
|
||||
if ($$ == 0) {
|
||||
parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString());
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ public:
|
|||
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
||||
TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc);
|
||||
TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc);
|
||||
TIntermTyped* addBuiltInFunctionCall(TSourceLoc line, TOperator, bool unary, TIntermNode*, const TType& returnType);
|
||||
bool canImplicitlyPromote(TBasicType from, TBasicType to) const;
|
||||
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue