Add uint type (big change). For both int/uint, add the operators >>, <<, &, |, and ^. Also added unsigned literals and uint precision support. Also fixed how int/uint literal underflow/overflow is handled.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21054 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
ae722a6230
commit
ebeeece6a7
@ -10,7 +10,11 @@ lowp vec2 foo(mediump vec3 mv3)
|
||||
|
||||
int global_medium;
|
||||
|
||||
precision highp int;
|
||||
precision highp int;
|
||||
precision highp ivec2; // ERROR
|
||||
precision mediump int[2]; // ERROR
|
||||
precision lowp uint; // ERROR
|
||||
precision mediump vec4; // ERROR
|
||||
|
||||
int global_high;
|
||||
|
||||
|
@ -3,22 +3,22 @@
|
||||
#extension GL_3DL_array_objects : enable
|
||||
|
||||
int a = 0xffffffff; // 32 bits, a gets the value -1
|
||||
//int b = 0xffffffffU; // ERROR: can't convert uint to int
|
||||
int b = 0xffffffffU; // ERROR: can't convert uint to int
|
||||
uint c = 0xffffffff; // 32 bits, c gets the value 0xFFFFFFFF
|
||||
//uint d = 0xffffffffU; // 32 bits, d gets the value 0xFFFFFFFF
|
||||
uint d = 0xffffffffU; // 32 bits, d gets the value 0xFFFFFFFF
|
||||
int e = -1; // the literal is "1", then negation is performed,
|
||||
// and the resulting non-literal 32-bit signed
|
||||
// bit pattern of 0xFFFFFFFF is assigned, giving e
|
||||
// the value of -1.
|
||||
//uint f = -1u; // the literal is "1u", then negation is performed,
|
||||
uint f = -1u; // the literal is "1u", then negation is performed,
|
||||
// and the resulting non-literal 32-bit unsigned
|
||||
// bit pattern of 0xFFFFFFFF is assigned, giving f
|
||||
// the value of 0xFFFFFFFF.
|
||||
int g = 3000000000; // a signed decimal literal taking 32 bits,
|
||||
// setting the sign bit, g gets -1294967296
|
||||
int h = 0xA0000000; // okay, 32-bit signed hexadecimal
|
||||
//int i = 5000000000; // ERROR: needs more than 32 bits
|
||||
//int j = 0xFFFFFFFFF; // ERROR: needs more that 32 bits
|
||||
int i = 5000000000; // ERROR: needs more than 32 bits
|
||||
int j = 0xFFFFFFFFF; // ERROR: needs more that 32 bits
|
||||
int k = 0x80000000; // k gets -2147483648 == 0x80000000
|
||||
int l = 2147483648; // l gets -2147483648 (the literal set the sign bit)
|
||||
|
||||
|
@ -29,3 +29,4 @@ constErrors.frag
|
||||
constFold.frag
|
||||
errors.frag
|
||||
forwardRef.frag
|
||||
uint.frag
|
||||
|
105
Test/uint.frag
Normal file
105
Test/uint.frag
Normal file
@ -0,0 +1,105 @@
|
||||
#version 300 es
|
||||
|
||||
in uvec2 t;
|
||||
in float f;
|
||||
in vec2 tc;
|
||||
|
||||
uniform uvec4 v;
|
||||
uniform int i;
|
||||
uniform bool b;
|
||||
|
||||
out uvec4 c;
|
||||
|
||||
uniform usampler2D usampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
uint u = t.y + 3u;
|
||||
const uint cu1error = 0xFFFFFFFF; // ERROR
|
||||
const uint cu1 = 0xFFFFFFFFU;
|
||||
const uint cu2 = -1u; // 0xFFFFFFFF
|
||||
const uint cu3 = 1U;
|
||||
const uint cu4error = 1; // ERROR
|
||||
const uint cu4 = 1u;
|
||||
|
||||
if (cu1 == cu2)
|
||||
count *= 2; // done
|
||||
if (cu3 == cu4)
|
||||
count *= 3; // done
|
||||
if (cu2 == cu3)
|
||||
count *= 5; // not done
|
||||
|
||||
const uint cushiftediierror = 0xFFFFFFFF >> 10; // ERROR
|
||||
const int cshiftedii = 0xFFFFFFFF >> 10;
|
||||
const uint cushiftedui = 0xFFFFFFFFu >> 10;
|
||||
const uint cushiftediuerror = 0xFFFFFFFF >> 10u; // ERROR
|
||||
const int cshiftediu = 0xFFFFFFFF >> 10u;
|
||||
const uint cushifteduu = 0xFFFFFFFFu >> 10u;
|
||||
|
||||
if (cshiftedii == cshiftediu)
|
||||
count *= 7; // done
|
||||
if (cushiftedui == cushifteduu)
|
||||
count *= 11; // done
|
||||
if (cshiftedii == int(cushiftedui))
|
||||
count *= 13; // not done
|
||||
|
||||
uint shiftediierror = 0xFFFFFFFF >> 10; // ERROR
|
||||
int shiftedii = 0xFFFFFFFF >> 10;
|
||||
uint shiftedui = 0xFFFFFFFFu >> 10;
|
||||
uint shiftediuerror = 0xFFFFFFFF >> 10u; // ERROR
|
||||
int shiftediu = 0xFFFFFFFF >> 10u;
|
||||
uint shifteduu = 0xFFFFFFFFu >> 10u;
|
||||
|
||||
if (shiftedii == shiftediu)
|
||||
c = texture(usampler, tc);
|
||||
if (shiftedui == shifteduu)
|
||||
c = texture(usampler, tc + float(1u));
|
||||
if (shiftedii == int(shiftedui))
|
||||
c = texture(usampler, tc - vec2(2u));
|
||||
|
||||
if (t.x > 4u) {
|
||||
float af = float(u);
|
||||
bool ab = bool(u);
|
||||
int ai = int(u);
|
||||
|
||||
c += uvec4(uint(af), uint(ab), uint(ai), count);
|
||||
}
|
||||
|
||||
const uint cmask1 = 0x0A1u;
|
||||
const uint cmask2 = 0xA10u;
|
||||
const uint cmask3 = cmask1 << 4;
|
||||
const uint cmask4 = 0xAB1u;
|
||||
|
||||
if (cmask3 == cmask2)
|
||||
count *= 17; // done
|
||||
|
||||
if ((cmask3 & cmask1) != 0u)
|
||||
count *= 19; // not done
|
||||
|
||||
if ((cmask1 | cmask3) == cmask4)
|
||||
count *= 23; // done
|
||||
|
||||
if ((cmask1 ^ cmask4) == 0xA10u)
|
||||
count *= 27; // done
|
||||
|
||||
uint mask1 = 0x0A1u;
|
||||
uint mask2 = 0xA10u;
|
||||
uint mask3 = mask1 << 4;
|
||||
uint mask4 = 0xAB1u;
|
||||
|
||||
if (mask3 == mask2)
|
||||
count *= 100;
|
||||
|
||||
if ((mask3 & mask1) != 0u)
|
||||
count *= 101;
|
||||
|
||||
if ((mask1 | mask3) == mask4)
|
||||
count *= 102;
|
||||
|
||||
if ((mask1 ^ mask4) == 0xA10u)
|
||||
count *= 103;
|
||||
|
||||
c += uvec4(count);
|
||||
}
|
@ -285,10 +285,21 @@ public:
|
||||
constUnion operator>>(const constUnion& constant) const
|
||||
{
|
||||
constUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
||||
case EbtInt:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
@ -298,10 +309,21 @@ public:
|
||||
constUnion operator<<(const constUnion& constant) const
|
||||
{
|
||||
constUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
||||
case EbtInt:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,11 @@ public:
|
||||
matrixCols = c;
|
||||
vectorSize = 0;
|
||||
}
|
||||
|
||||
bool isScalar()
|
||||
{
|
||||
return matrixCols == 0 && vectorSize == 1 && arraySizes == 0 && userDef == 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<TTypeList*, TTypeList*> TStructureMap;
|
||||
|
@ -75,11 +75,25 @@ enum TOperator {
|
||||
EOpPreDecrement,
|
||||
|
||||
EOpConvIntToBool,
|
||||
EOpConvUintToBool,
|
||||
EOpConvFloatToBool,
|
||||
EOpConvDoubleToBool,
|
||||
EOpConvBoolToFloat,
|
||||
EOpConvIntToFloat,
|
||||
EOpConvUintToFloat,
|
||||
EOpConvDoubleToFloat,
|
||||
EOpConvUintToInt,
|
||||
EOpConvFloatToInt,
|
||||
EOpConvBoolToInt,
|
||||
EOpConvDoubleToInt,
|
||||
EOpConvIntToUint,
|
||||
EOpConvFloatToUint,
|
||||
EOpConvBoolToUint,
|
||||
EOpConvDoubleToUint,
|
||||
EOpConvIntToDouble,
|
||||
EOpConvUintToDouble,
|
||||
EOpConvFloatToDouble,
|
||||
EOpConvBoolToDouble,
|
||||
|
||||
//
|
||||
// binary operations
|
||||
@ -192,6 +206,7 @@ enum TOperator {
|
||||
|
||||
EOpConstructGuardStart,
|
||||
EOpConstructInt,
|
||||
EOpConstructUint,
|
||||
EOpConstructBool,
|
||||
EOpConstructFloat,
|
||||
EOpConstructDouble,
|
||||
@ -207,6 +222,9 @@ enum TOperator {
|
||||
EOpConstructIVec2,
|
||||
EOpConstructIVec3,
|
||||
EOpConstructIVec4,
|
||||
EOpConstructUVec2,
|
||||
EOpConstructUVec3,
|
||||
EOpConstructUVec4,
|
||||
EOpConstructMat2x2,
|
||||
EOpConstructMat2x3,
|
||||
EOpConstructMat2x4,
|
||||
|
@ -120,11 +120,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
||||
TIntermConstantUnion *node = constantNode->getAsConstantUnion();
|
||||
constUnion *rightUnionArray = node->getUnionArrayPointer();
|
||||
|
||||
if (getType().getBasicType() != node->getBasicType()) {
|
||||
infoSink.info.message(EPrefixInternalError, "Constant folding basic types don't match", getLine());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
|
||||
// for a case like float f = vec4(2,3,4,5) + 1.2;
|
||||
rightUnionArray = new constUnion[objectSize];
|
||||
@ -190,6 +185,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
|
||||
} else
|
||||
newConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
||||
break;
|
||||
|
||||
case EbtUint:
|
||||
if (rightUnionArray[i] == 0) {
|
||||
newConstArray[i].setUConst(0xFFFFFFFF);
|
||||
} else
|
||||
newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
|
||||
return 0;
|
||||
@ -388,6 +390,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
|
||||
switch (getType().getBasicType()) {
|
||||
case EbtFloat: newConstArray[i].setFConst(-unionArray[i].getFConst()); break;
|
||||
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
||||
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
|
||||
return 0;
|
||||
|
@ -227,9 +227,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
|
||||
//
|
||||
TBasicType newType = EbtVoid;
|
||||
switch (op) {
|
||||
case EOpConstructInt: newType = EbtInt; break;
|
||||
case EOpConstructBool: newType = EbtBool; break;
|
||||
case EOpConstructFloat: newType = EbtFloat; break;
|
||||
case EOpConstructInt: newType = EbtInt; break;
|
||||
case EOpConstructUint: newType = EbtUint; break;
|
||||
case EOpConstructBool: newType = EbtBool; break;
|
||||
case EOpConstructFloat: newType = EbtFloat; break;
|
||||
case EOpConstructDouble: newType = EbtDouble; break;
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
@ -248,6 +249,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
|
||||
//
|
||||
switch (op) {
|
||||
case EOpConstructInt:
|
||||
case EOpConstructUint:
|
||||
case EOpConstructBool:
|
||||
case EOpConstructFloat:
|
||||
case EOpConstructDouble:
|
||||
@ -380,6 +382,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||
case EOpConstructInt:
|
||||
promoteTo = EbtInt;
|
||||
break;
|
||||
case EOpConstructUint:
|
||||
promoteTo = EbtUint;
|
||||
break;
|
||||
|
||||
//
|
||||
// List all the binary ops that can implicitly convert one operand to the other's type;
|
||||
@ -424,6 +429,22 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||
|
||||
break;
|
||||
|
||||
// Shifts can have mixed types as long as they are integer, without converting.
|
||||
// It's the left operand's type that determines the resulting type, so no issue
|
||||
// with assign shift ops either.
|
||||
case EOpLeftShift:
|
||||
case EOpRightShift:
|
||||
case EOpLeftShiftAssign:
|
||||
case EOpRightShiftAssign:
|
||||
if ((type.getBasicType() == EbtInt ||
|
||||
type.getBasicType() == EbtUint) &&
|
||||
(node->getType().getBasicType() == EbtInt ||
|
||||
node->getType().getBasicType() == EbtUint))
|
||||
|
||||
return node;
|
||||
else
|
||||
return 0;
|
||||
|
||||
default:
|
||||
// default is to require a match; all exceptions should have case statements above
|
||||
|
||||
@ -449,37 +470,55 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
|
||||
switch (promoteTo) {
|
||||
case EbtDouble:
|
||||
//switch (node->getBasicType()) {
|
||||
//case EbtInt: newOp = EOpConvIntToDouble; break;
|
||||
//case EbtBool: newOp = EOpConvBoolToDouble; break;
|
||||
//case EbtFloat: newOp = EOpConvFloatToDouble; break;
|
||||
//default:
|
||||
//case EbtInt: newOp = EOpConvIntToDouble; break;
|
||||
//case EbtUint: newOp = EOpConvUintToDouble; break;
|
||||
//case EbtBool: newOp = EOpConvBoolToDouble; break;
|
||||
//case EbtFloat: newOp = EOpConvFloatToDouble; break;
|
||||
//default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
return 0;
|
||||
//}
|
||||
break;
|
||||
case EbtFloat:
|
||||
switch (node->getBasicType()) {
|
||||
case EbtInt: newOp = EOpConvIntToFloat; break;
|
||||
case EbtBool: newOp = EOpConvBoolToFloat; break;
|
||||
default:
|
||||
case EbtInt: newOp = EOpConvIntToFloat; break;
|
||||
case EbtUint: newOp = EOpConvUintToFloat; break;
|
||||
case EbtBool: newOp = EOpConvBoolToFloat; break;
|
||||
case EbtDouble: newOp = EOpConvDoubleToFloat; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EbtBool:
|
||||
switch (node->getBasicType()) {
|
||||
case EbtInt: newOp = EOpConvIntToBool; break;
|
||||
case EbtFloat: newOp = EOpConvFloatToBool; break;
|
||||
default:
|
||||
case EbtInt: newOp = EOpConvIntToBool; break;
|
||||
case EbtUint: newOp = EOpConvUintToBool; break;
|
||||
case EbtFloat: newOp = EOpConvFloatToBool; break;
|
||||
case EbtDouble: newOp = EOpConvDoubleToBool; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EbtInt:
|
||||
switch (node->getBasicType()) {
|
||||
case EbtUint: newOp = EOpConvUintToInt; break;
|
||||
case EbtBool: newOp = EOpConvBoolToInt; break;
|
||||
case EbtFloat: newOp = EOpConvFloatToInt; break;
|
||||
default:
|
||||
case EbtDouble: newOp = EOpConvDoubleToInt; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch (node->getBasicType()) {
|
||||
case EbtInt: newOp = EOpConvIntToUint; break;
|
||||
case EbtBool: newOp = EOpConvBoolToUint; break;
|
||||
case EbtFloat: newOp = EOpConvFloatToUint; break;
|
||||
case EbtDouble: newOp = EOpConvDoubleToUint; break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
@ -978,7 +1017,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
||||
break;
|
||||
|
||||
//
|
||||
// And and Or operate on conditionals
|
||||
// And and Or operate only on conditionals
|
||||
//
|
||||
case EOpLogicalAnd:
|
||||
case EOpLogicalOr:
|
||||
@ -996,7 +1035,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
||||
case EOpAnd:
|
||||
case EOpInclusiveOr:
|
||||
case EOpExclusiveOr:
|
||||
if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt)
|
||||
if ( left->getBasicType() != EbtInt && left->getBasicType() != EbtUint ||
|
||||
right->getBasicType() != EbtInt && right->getBasicType() != EbtUint)
|
||||
return false;
|
||||
break;
|
||||
case EOpModAssign:
|
||||
@ -1005,7 +1045,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
||||
case EOpExclusiveOrAssign:
|
||||
case EOpLeftShiftAssign:
|
||||
case EOpRightShiftAssign:
|
||||
if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt)
|
||||
if ( left->getBasicType() != EbtInt && left->getBasicType() != EbtUint ||
|
||||
right->getBasicType() != EbtInt && right->getBasicType() != EbtUint)
|
||||
return false;
|
||||
// fall through
|
||||
|
||||
@ -1166,7 +1207,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
|
||||
|
||||
void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
|
||||
{
|
||||
if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtFloat))
|
||||
if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat))
|
||||
return;
|
||||
|
||||
getQualifier().precision = newPrecision;
|
||||
@ -1228,12 +1269,40 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
||||
case EbtInt:
|
||||
leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getIConst()));
|
||||
break;
|
||||
case EbtUint:
|
||||
leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getUConst()));
|
||||
break;
|
||||
case EbtBool:
|
||||
leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getBConst()));
|
||||
break;
|
||||
case EbtFloat:
|
||||
leftUnionArray[i] = rightUnionArray[i];
|
||||
break;
|
||||
case EbtDouble:
|
||||
leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getBConst()));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EbtDouble:
|
||||
switch (node->getType().getBasicType()) {
|
||||
case EbtInt:
|
||||
leftUnionArray[i].setDConst(static_cast<float>(rightUnionArray[i].getIConst()));
|
||||
break;
|
||||
case EbtUint:
|
||||
leftUnionArray[i].setDConst(static_cast<float>(rightUnionArray[i].getUConst()));
|
||||
break;
|
||||
case EbtBool:
|
||||
leftUnionArray[i].setDConst(static_cast<float>(rightUnionArray[i].getBConst()));
|
||||
break;
|
||||
case EbtFloat:
|
||||
leftUnionArray[i].setDConst(static_cast<float>(rightUnionArray[i].getFConst()));
|
||||
break;
|
||||
case EbtDouble:
|
||||
leftUnionArray[i] = rightUnionArray[i];
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
return 0;
|
||||
@ -1244,12 +1313,40 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
||||
case EbtInt:
|
||||
leftUnionArray[i] = rightUnionArray[i];
|
||||
break;
|
||||
case EbtUint:
|
||||
leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst()));
|
||||
break;
|
||||
case EbtBool:
|
||||
leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
|
||||
break;
|
||||
case EbtFloat:
|
||||
leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getFConst()));
|
||||
break;
|
||||
case EbtDouble:
|
||||
leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst()));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch (node->getType().getBasicType()) {
|
||||
case EbtInt:
|
||||
leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst()));
|
||||
break;
|
||||
case EbtUint:
|
||||
leftUnionArray[i] = rightUnionArray[i];
|
||||
break;
|
||||
case EbtBool:
|
||||
leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst()));
|
||||
break;
|
||||
case EbtFloat:
|
||||
leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getFConst()));
|
||||
break;
|
||||
case EbtDouble:
|
||||
leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst()));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
return 0;
|
||||
@ -1260,17 +1357,22 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
||||
case EbtInt:
|
||||
leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
|
||||
break;
|
||||
case EbtUint:
|
||||
leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0);
|
||||
break;
|
||||
case EbtBool:
|
||||
leftUnionArray[i] = rightUnionArray[i];
|
||||
break;
|
||||
case EbtFloat:
|
||||
leftUnionArray[i].setBConst(rightUnionArray[i].getFConst() != 0.0f);
|
||||
break;
|
||||
case EbtDouble:
|
||||
leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0f);
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
|
||||
|
@ -54,12 +54,14 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E
|
||||
switch (language) {
|
||||
case EShLangVertex:
|
||||
defaultPrecision[EbtInt] = EpqHigh;
|
||||
defaultPrecision[EbtUint] = EpqHigh;
|
||||
defaultPrecision[EbtFloat] = EpqHigh;
|
||||
defaultPrecision[EbtSampler] = EpqLow;
|
||||
// TODO: functionality: need default precisions per sampler type
|
||||
break;
|
||||
case EShLangFragment:
|
||||
defaultPrecision[EbtInt] = EpqMedium;
|
||||
defaultPrecision[EbtUint] = EpqMedium;
|
||||
defaultPrecision[EbtSampler] = EpqLow;
|
||||
// TODO: give error when using float in frag shader without default precision
|
||||
break;
|
||||
@ -399,10 +401,10 @@ bool TParseContext::constErrorCheck(TIntermTyped* node)
|
||||
//
|
||||
bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
|
||||
{
|
||||
if (node->getBasicType() == EbtInt && node->getVectorSize() == 1)
|
||||
if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->getVectorSize() == 1 && ! node->isArray())
|
||||
return false;
|
||||
|
||||
error(node->getLine(), "integer expression required", token, "");
|
||||
error(node->getLine(), "scalar integer expression required", token, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -728,14 +730,22 @@ bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& left, const
|
||||
return bad;
|
||||
}
|
||||
|
||||
void TParseContext::setDefaultPrecision(int line, TBasicType type, TPrecisionQualifier qualifier)
|
||||
void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrecisionQualifier qualifier)
|
||||
{
|
||||
if (type == EbtSampler || type == EbtInt || type == EbtFloat) {
|
||||
defaultPrecision[type] = qualifier;
|
||||
} else {
|
||||
error(line, "cannot apply precision statement to this type", TType::getBasicString(type), "");
|
||||
recover();
|
||||
TBasicType basicType = publicType.type;
|
||||
|
||||
if (basicType == EbtSampler || basicType == EbtInt || basicType == EbtFloat) {
|
||||
if (publicType.isScalar()) {
|
||||
defaultPrecision[basicType] = qualifier;
|
||||
if (basicType == EbtInt)
|
||||
defaultPrecision[EbtUint] = qualifier;
|
||||
|
||||
return; // all is well
|
||||
}
|
||||
}
|
||||
|
||||
error(line, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), "");
|
||||
recover();
|
||||
}
|
||||
|
||||
bool TParseContext::parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type)
|
||||
@ -800,7 +810,7 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel()
|
||||
bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
|
||||
{
|
||||
TIntermConstantUnion* constant = expr->getAsConstantUnion();
|
||||
if (constant == 0 || constant->getBasicType() != EbtInt) {
|
||||
if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) {
|
||||
error(line, "array size must be a constant integer expression", "", "");
|
||||
size = 1;
|
||||
return true;
|
||||
@ -1299,6 +1309,13 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
||||
basicOp = EOpConstructInt;
|
||||
break;
|
||||
|
||||
case EOpConstructUVec2:
|
||||
case EOpConstructUVec3:
|
||||
case EOpConstructUVec4:
|
||||
case EOpConstructUint:
|
||||
basicOp = EOpConstructUint;
|
||||
break;
|
||||
|
||||
case EOpConstructBVec2:
|
||||
case EOpConstructBVec3:
|
||||
case EOpConstructBVec4:
|
||||
|
@ -123,7 +123,7 @@ struct TParseContext {
|
||||
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
|
||||
bool structQualifierErrorCheck(int line, const TPublicType& pType);
|
||||
bool mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right);
|
||||
void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
|
||||
void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier);
|
||||
bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
|
||||
bool containsSampler(const TType& type);
|
||||
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||
@ -146,6 +146,8 @@ struct TParseContext {
|
||||
void profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc);
|
||||
void checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc);
|
||||
void requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc);
|
||||
void fullIntegerCheck(int line, const char* op);
|
||||
void doubleCheck(int line, const char* op);
|
||||
};
|
||||
|
||||
int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
|
||||
|
@ -59,6 +59,7 @@ void TType::buildMangledName(TString& mangledName)
|
||||
case EbtFloat: mangledName += 'f'; break;
|
||||
case EbtDouble: mangledName += 'd'; break;
|
||||
case EbtInt: mangledName += 'i'; break;
|
||||
case EbtUint: mangledName += 'u'; break;
|
||||
case EbtBool: mangledName += 'b'; break;
|
||||
case EbtSampler:
|
||||
switch (sampler.type) {
|
||||
|
@ -160,3 +160,16 @@ void TParseContext::requireNotRemoved(int line, EProfile callingProfile, int rem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TParseContext::fullIntegerCheck(int line, const char* op)
|
||||
{
|
||||
profileRequires(line, ENoProfile, 130, 0, op);
|
||||
profileRequires(line, EEsProfile, 300, 0, op);
|
||||
}
|
||||
|
||||
void TParseContext::doubleCheck(int line, const char* op)
|
||||
{
|
||||
requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op);
|
||||
profileRequires(line, ECoreProfile, 400, 0, op);
|
||||
profileRequires(line, ECompatibilityProfile, 400, 0, op);
|
||||
}
|
||||
|
@ -355,15 +355,15 @@ int yy_input(char* buf, int max_size);
|
||||
return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol);
|
||||
}
|
||||
|
||||
0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
|
||||
0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
|
||||
0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return(INTCONSTANT); }
|
||||
0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return(INTCONSTANT); }
|
||||
0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
|
||||
{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
|
||||
{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return(INTCONSTANT); }
|
||||
|
||||
0[xX]{H}+{U} { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(UINTCONSTANT); }
|
||||
0{O}+{U} { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(UINTCONSTANT); }
|
||||
0[xX]{H}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return(UINTCONSTANT); }
|
||||
0{O}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return(UINTCONSTANT); }
|
||||
0{D}+{U} { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
|
||||
{D}+{U} { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(UINTCONSTANT); }
|
||||
{D}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return(UINTCONSTANT); }
|
||||
|
||||
{D}+{F} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
|
||||
{D}+{E}{F}? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
|
||||
|
@ -82,6 +82,7 @@ extern void yyerror(const char*);
|
||||
TString *string;
|
||||
float f;
|
||||
int i;
|
||||
unsigned int u;
|
||||
bool b;
|
||||
double d;
|
||||
};
|
||||
@ -120,7 +121,7 @@ extern void yyerror(const char*);
|
||||
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT
|
||||
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE
|
||||
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
|
||||
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
|
||||
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
|
||||
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED
|
||||
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
|
||||
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
|
||||
@ -146,20 +147,20 @@ extern void yyerror(const char*);
|
||||
%token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
|
||||
%token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
|
||||
|
||||
%token <lex> IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D
|
||||
%token <lex> IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D
|
||||
%token <lex> UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D
|
||||
%token <lex> IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT
|
||||
%token <lex> IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT
|
||||
%token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
|
||||
%token <lex> IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
|
||||
%token <lex> IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY
|
||||
%token <lex> IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY
|
||||
%token <lex> IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
|
||||
%token <lex> IMAGECUBEARRAY IIMAGECUBEARRAY UIMAGECUBEARRAY
|
||||
%token <lex> IMAGE2DMS IIMAGE2DMS UIMAGE2DMS
|
||||
%token <lex> IMAGE2DMS IIMAGE2DMS UIMAGE2DMS
|
||||
%token <lex> IMAGE2DMSARRAY IIMAGE2DMSARRAY UIMAGE2DMSARRAY
|
||||
|
||||
%token <lex> STRUCT VOID WHILE
|
||||
|
||||
%token <lex> IDENTIFIER TYPE_NAME
|
||||
%token <lex> IDENTIFIER TYPE_NAME
|
||||
%token <lex> FLOATCONSTANT DOUBLECONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
|
||||
%token <lex> FIELD_SELECTION
|
||||
%token <lex> LEFT_OP RIGHT_OP
|
||||
@ -254,10 +255,11 @@ primary_expression
|
||||
unionArray->setIConst($1.i);
|
||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
| UINTCONSTANT {
|
||||
parseContext.fullIntegerCheck($1.line, "unsigned literal");
|
||||
constUnion *unionArray = new constUnion[1];
|
||||
unionArray->setIConst($1.i);
|
||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
|
||||
unionArray->setUConst($1.u);
|
||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.line);
|
||||
}
|
||||
| FLOATCONSTANT {
|
||||
constUnion *unionArray = new constUnion[1];
|
||||
@ -265,6 +267,7 @@ primary_expression
|
||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
|
||||
}
|
||||
| DOUBLECONSTANT {
|
||||
parseContext.doubleCheck($1.line, "double literal");
|
||||
constUnion *unionArray = new constUnion[1];
|
||||
unionArray->setDConst($1.d);
|
||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.line);
|
||||
@ -538,7 +541,7 @@ function_call
|
||||
//
|
||||
if (fnCandidate->getParamCount() == 1) {
|
||||
//
|
||||
// Treat it like a built-in unary operator.
|
||||
// Treat it like a built-in unary operator.
|
||||
// addUnaryMath() should get the type correct on its own;
|
||||
// including constness (which would differ from the prototype).
|
||||
//
|
||||
@ -748,6 +751,15 @@ function_identifier
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch($1.vectorSize) {
|
||||
case 1: op = EOpConstructUint; break;
|
||||
case 2: op = EOpConstructUVec2; break;
|
||||
case 3: op = EOpConstructUVec3; break;
|
||||
case 4: op = EOpConstructUVec4; break;
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
break;
|
||||
case EbtBool:
|
||||
switch($1.vectorSize) {
|
||||
case 1: op = EOpConstructBool; break;
|
||||
@ -913,6 +925,7 @@ additive_expression
|
||||
shift_expression
|
||||
: additive_expression { $$ = $1; }
|
||||
| shift_expression LEFT_OP additive_expression {
|
||||
parseContext.fullIntegerCheck($2.line, "bit shift left");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line, parseContext.symbolTable);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString());
|
||||
@ -921,6 +934,7 @@ shift_expression
|
||||
}
|
||||
}
|
||||
| shift_expression RIGHT_OP additive_expression {
|
||||
parseContext.fullIntegerCheck($2.line, "bit shift right");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line, parseContext.symbolTable);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString());
|
||||
@ -1003,6 +1017,7 @@ equality_expression
|
||||
and_expression
|
||||
: equality_expression { $$ = $1; }
|
||||
| and_expression AMPERSAND equality_expression {
|
||||
parseContext.fullIntegerCheck($2.line, "bitwise and");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line, parseContext.symbolTable);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString());
|
||||
@ -1015,6 +1030,7 @@ and_expression
|
||||
exclusive_or_expression
|
||||
: and_expression { $$ = $1; }
|
||||
| exclusive_or_expression CARET and_expression {
|
||||
parseContext.fullIntegerCheck($2.line, "bitwise exclusive or");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString());
|
||||
@ -1027,6 +1043,7 @@ exclusive_or_expression
|
||||
inclusive_or_expression
|
||||
: exclusive_or_expression { $$ = $1; }
|
||||
| inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
|
||||
parseContext.fullIntegerCheck($2.line, "bitwise inclusive or");
|
||||
$$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
|
||||
if ($$ == 0) {
|
||||
parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString());
|
||||
@ -1115,11 +1132,26 @@ assignment_operator
|
||||
| MOD_ASSIGN { $$.line = $1.line; $$.op = EOpModAssign; }
|
||||
| ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; }
|
||||
| SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; }
|
||||
| LEFT_ASSIGN { $$.line = $1.line; $$.op = EOpLeftShiftAssign; }
|
||||
| RIGHT_ASSIGN { $$.line = $1.line; $$.op = EOpRightShiftAssign; }
|
||||
| AND_ASSIGN { $$.line = $1.line; $$.op = EOpAndAssign; }
|
||||
| XOR_ASSIGN { $$.line = $1.line; $$.op = EOpExclusiveOrAssign; }
|
||||
| OR_ASSIGN { $$.line = $1.line; $$.op = EOpInclusiveOrAssign; }
|
||||
| LEFT_ASSIGN {
|
||||
parseContext.fullIntegerCheck($1.line, "bit-shift left assign");
|
||||
$$.line = $1.line; $$.op = EOpLeftShiftAssign;
|
||||
}
|
||||
| RIGHT_ASSIGN {
|
||||
parseContext.fullIntegerCheck($1.line, "bit-shift right assign");
|
||||
$$.line = $1.line; $$.op = EOpRightShiftAssign;
|
||||
}
|
||||
| AND_ASSIGN {
|
||||
parseContext.fullIntegerCheck($1.line, "bitwise-and assign");
|
||||
$$.line = $1.line; $$.op = EOpAndAssign;
|
||||
}
|
||||
| XOR_ASSIGN {
|
||||
parseContext.fullIntegerCheck($1.line, "bitwise-xor assign");
|
||||
$$.line = $1.line; $$.op = EOpExclusiveOrAssign;
|
||||
}
|
||||
| OR_ASSIGN {
|
||||
parseContext.fullIntegerCheck($1.line, "bitwise-or assign");
|
||||
$$.line = $1.line; $$.op = EOpInclusiveOrAssign;
|
||||
}
|
||||
;
|
||||
|
||||
expression
|
||||
@ -1156,11 +1188,11 @@ declaration
|
||||
}
|
||||
| PRECISION precision_qualifier type_specifier SEMICOLON {
|
||||
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "precision statement");
|
||||
|
||||
|
||||
// lazy setting of the previous scope's defaults, only takes on first one in a particular scope
|
||||
parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]);
|
||||
|
||||
parseContext.setDefaultPrecision($1.line, $3.type, $2.qualifier.precision);
|
||||
parseContext.setDefaultPrecision($1.line, $3, $2.qualifier.precision);
|
||||
$$ = 0;
|
||||
}
|
||||
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON {
|
||||
@ -1217,7 +1249,7 @@ function_prototype
|
||||
}
|
||||
for (int i = 0; i < prevDec->getParamCount(); ++i) {
|
||||
if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage) {
|
||||
parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers",
|
||||
parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers",
|
||||
(*$1)[i].type->getStorageQualifierString(), "");
|
||||
parseContext.recover();
|
||||
}
|
||||
@ -1278,7 +1310,7 @@ function_header_with_parameters
|
||||
function_header
|
||||
: fully_specified_type IDENTIFIER LEFT_PAREN {
|
||||
if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) {
|
||||
parseContext.error($2.line, "no qualifiers allowed for function return",
|
||||
parseContext.error($2.line, "no qualifiers allowed for function return",
|
||||
getStorageQualifierString($1.qualifier.storage), "");
|
||||
parseContext.recover();
|
||||
}
|
||||
@ -1307,7 +1339,7 @@ parameter_declarator
|
||||
}
|
||||
if (parseContext.reservedErrorCheck($2.line, *$2.string))
|
||||
parseContext.recover();
|
||||
|
||||
|
||||
TParameter param = {$2.string, new TType($1)};
|
||||
$$.line = $2.line;
|
||||
$$.param = param;
|
||||
@ -1361,7 +1393,7 @@ parameter_declaration
|
||||
$$ = $2;
|
||||
if ($1.qualifier.precision != EpqNone)
|
||||
$$.param.type->getQualifier().precision = $1.qualifier.precision;
|
||||
|
||||
|
||||
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier.storage, *$$.param.type))
|
||||
parseContext.recover();
|
||||
if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type))
|
||||
@ -1595,12 +1627,12 @@ fully_specified_type
|
||||
}
|
||||
|
||||
if ($1.qualifier.storage == EvqAttribute &&
|
||||
($2.type == EbtBool || $2.type == EbtInt)) {
|
||||
($2.type == EbtBool || $2.type == EbtInt || $2.type == EbtUint)) {
|
||||
parseContext.error($2.line, "cannot be bool or int", getStorageQualifierString($1.qualifier.storage), "");
|
||||
parseContext.recover();
|
||||
}
|
||||
if (($1.qualifier.storage == EvqVaryingIn || $1.qualifier.storage == EvqVaryingOut) &&
|
||||
($2.type == EbtBool || $2.type == EbtInt)) {
|
||||
($2.type == EbtBool || $2.type == EbtInt || $2.type == EbtUint)) {
|
||||
parseContext.error($2.line, "cannot be bool or int", getStorageQualifierString($1.qualifier.storage), "");
|
||||
parseContext.recover();
|
||||
}
|
||||
@ -1734,12 +1766,12 @@ storage_qualifier
|
||||
parseContext.checkDeprecated($1.line, ECoreProfile, 150, "varying");
|
||||
parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "varying");
|
||||
parseContext.requireNotRemoved($1.line, EEsProfile, 300, "varying");
|
||||
|
||||
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
|
||||
parseContext.recover();
|
||||
|
||||
$$.init($1.line);
|
||||
if (parseContext.language == EShLangVertex)
|
||||
if (parseContext.language == EShLangVertex)
|
||||
$$.qualifier.storage = EvqVaryingOut;
|
||||
else
|
||||
$$.qualifier.storage = EvqVaryingIn;
|
||||
@ -1792,7 +1824,7 @@ storage_qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.buffer = true;
|
||||
}
|
||||
| SHARED {
|
||||
@ -1896,6 +1928,7 @@ type_specifier_nonarray
|
||||
$$.type = EbtFloat;
|
||||
}
|
||||
| DOUBLE {
|
||||
parseContext.doubleCheck($1.line, "double");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
}
|
||||
@ -1904,9 +1937,9 @@ type_specifier_nonarray
|
||||
$$.type = EbtInt;
|
||||
}
|
||||
| UINT {
|
||||
// TODO: implement EbtUint, check all int types
|
||||
parseContext.fullIntegerCheck($1.line, "unsigned integer");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtInt;
|
||||
$$.type = EbtUint;
|
||||
}
|
||||
| BOOL {
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
@ -1928,16 +1961,19 @@ type_specifier_nonarray
|
||||
$$.setVector(4);
|
||||
}
|
||||
| DVEC2 {
|
||||
parseContext.doubleCheck($1.line, "double vector");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setVector(2);
|
||||
}
|
||||
| DVEC3 {
|
||||
parseContext.doubleCheck($1.line, "double vector");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setVector(3);
|
||||
}
|
||||
| DVEC4 {
|
||||
parseContext.doubleCheck($1.line, "double vector");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setVector(4);
|
||||
@ -1973,18 +2009,21 @@ type_specifier_nonarray
|
||||
$$.setVector(4);
|
||||
}
|
||||
| UVEC2 {
|
||||
parseContext.fullIntegerCheck($1.line, "unsigned integer vector");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtInt;
|
||||
$$.type = EbtUint;
|
||||
$$.setVector(2);
|
||||
}
|
||||
| UVEC3 {
|
||||
parseContext.fullIntegerCheck($1.line, "unsigned integer vector");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtInt;
|
||||
$$.type = EbtUint;
|
||||
$$.setVector(3);
|
||||
}
|
||||
| UVEC4 {
|
||||
parseContext.fullIntegerCheck($1.line, "unsigned integer vector");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtInt;
|
||||
$$.type = EbtUint;
|
||||
$$.setVector(4);
|
||||
}
|
||||
| MAT2 {
|
||||
@ -2048,61 +2087,73 @@ type_specifier_nonarray
|
||||
$$.setMatrix(4, 4);
|
||||
}
|
||||
| DMAT2 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(2, 2);
|
||||
}
|
||||
| DMAT3 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(3, 3);
|
||||
}
|
||||
| DMAT4 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(4, 4);
|
||||
}
|
||||
| DMAT2X2 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(2, 2);
|
||||
}
|
||||
| DMAT2X3 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(2, 3);
|
||||
}
|
||||
| DMAT2X4 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(2, 4);
|
||||
}
|
||||
| DMAT3X2 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(3, 2);
|
||||
}
|
||||
| DMAT3X3 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(3, 3);
|
||||
}
|
||||
| DMAT3X4 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(3, 4);
|
||||
}
|
||||
| DMAT4X2 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(4, 2);
|
||||
}
|
||||
| DMAT4X3 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(4, 3);
|
||||
}
|
||||
| DMAT4X4 {
|
||||
parseContext.doubleCheck($1.line, "double matrix");
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtDouble;
|
||||
$$.setMatrix(4, 4);
|
||||
@ -2494,7 +2545,7 @@ type_specifier_nonarray
|
||||
// This is for user defined type names. The lexical phase looked up the
|
||||
// type.
|
||||
//
|
||||
if (TVariable* variable = ($1.symbol)->getAsVariable()) {
|
||||
if (TVariable* variable = ($1.symbol)->getAsVariable()) {
|
||||
const TType& structure = variable->getType();
|
||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.type = EbtStruct;
|
||||
@ -2642,10 +2693,10 @@ initializer
|
||||
: assignment_expression {
|
||||
$$ = $1;
|
||||
}
|
||||
| LEFT_BRACE initializer_list RIGHT_BRACE {
|
||||
| LEFT_BRACE initializer_list RIGHT_BRACE {
|
||||
$$ = $2;
|
||||
}
|
||||
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
|
||||
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
@ -2683,8 +2734,8 @@ simple_statement
|
||||
|
||||
compound_statement
|
||||
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
|
||||
| LEFT_BRACE { parseContext.symbolTable.push(); }
|
||||
statement_list { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); }
|
||||
| LEFT_BRACE { parseContext.symbolTable.push(); }
|
||||
statement_list { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); }
|
||||
RIGHT_BRACE {
|
||||
if ($3 != 0)
|
||||
$3->setOperator(EOpSequence);
|
||||
@ -2790,9 +2841,9 @@ case_label
|
||||
;
|
||||
|
||||
iteration_statement
|
||||
: WHILE LEFT_PAREN {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
: WHILE LEFT_PAREN {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
}
|
||||
condition RIGHT_PAREN statement_no_new_scope {
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
@ -2806,10 +2857,10 @@ iteration_statement
|
||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);
|
||||
--parseContext.loopNestingLevel;
|
||||
}
|
||||
| FOR LEFT_PAREN {
|
||||
| FOR LEFT_PAREN {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
}
|
||||
++parseContext.loopNestingLevel;
|
||||
}
|
||||
for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
$$ = parseContext.intermediate.makeAggregate($4, $2.line);
|
||||
@ -2941,7 +2992,7 @@ function_definition
|
||||
// Remember the return type for later checking for RETURN statements.
|
||||
//
|
||||
parseContext.currentFunctionType = &(prevDec->getReturnType());
|
||||
} else
|
||||
} else
|
||||
parseContext.currentFunctionType = new TType(EbtVoid);
|
||||
parseContext.functionReturnsValue = false;
|
||||
|
||||
|
@ -176,12 +176,26 @@ bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
|
||||
case EOpPreIncrement: out.debug << "Pre-Increment"; break;
|
||||
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
|
||||
|
||||
case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
|
||||
case EOpConvFloatToBool:out.debug << "Convert float to bool";break;
|
||||
case EOpConvBoolToFloat:out.debug << "Convert bool to float";break;
|
||||
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
|
||||
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
|
||||
case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
|
||||
case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
|
||||
case EOpConvUintToBool: out.debug << "Convert uint to bool"; break;
|
||||
case EOpConvFloatToBool: out.debug << "Convert float to bool"; break;
|
||||
case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break;
|
||||
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
|
||||
case EOpConvUintToFloat: out.debug << "Convert uint to float"; break;
|
||||
case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break;
|
||||
case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break;
|
||||
case EOpConvUintToInt: out.debug << "Convert uint to int"; break;
|
||||
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
|
||||
case EOpConvDoubleToInt: out.debug << "Convert double to int"; break;
|
||||
case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
|
||||
case EOpConvIntToUint: out.debug << "Convert int to uint"; break;
|
||||
case EOpConvFloatToUint: out.debug << "Convert float to uint"; break;
|
||||
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
|
||||
case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break;
|
||||
case EOpConvIntToDouble: out.debug << "Convert int to double"; break;
|
||||
case EOpConvUintToDouble: out.debug << "Convert uint to double"; break;
|
||||
case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
|
||||
case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break;
|
||||
|
||||
case EOpRadians: out.debug << "radians"; break;
|
||||
case EOpDegrees: out.debug << "degrees"; break;
|
||||
@ -258,6 +272,10 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
|
||||
case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
|
||||
case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
|
||||
case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
|
||||
case EOpConstructUint: out.debug << "Construct uint"; break;
|
||||
case EOpConstructUVec2: out.debug << "Construct uvec2"; break;
|
||||
case EOpConstructUVec3: out.debug << "Construct uvec3"; break;
|
||||
case EOpConstructUVec4: out.debug << "Construct uvec4"; break;
|
||||
case EOpConstructMat2x2: out.debug << "Construct mat2"; break;
|
||||
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
|
||||
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
|
||||
@ -398,6 +416,15 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
|
||||
out.debug << buf << "\n";
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
{
|
||||
const int maxSize = 300;
|
||||
char buf[maxSize];
|
||||
snprintf(buf, maxSize, "%u (%s)", node->getUnionArrayPointer()[i].getUConst(), "const uint");
|
||||
|
||||
out.debug << buf << "\n";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user