Commit 75694fda by John Kessenich

Implement implicit conversions of function-call arguments (both in and out) as…

Implement implicit conversions of function-call arguments (both in and out) as explicit conversions in the AST, through handleArgumentConversions(). Also - uniformly handle EvqConstReadOnly as an input argument in a function, with isParamInput() and isParamOutput() queries in TQualifier. - provide a makeTemporary() in TQualifier, for erasing original qualification when making a temp - provide a makeInternalVariable() call to make a shader variable not seen in the shader source git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@25912 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent e5d92eb1
...@@ -58,15 +58,15 @@ float overloadA(float); // ERROR, different return value for same sig ...@@ -58,15 +58,15 @@ float overloadA(float); // ERROR, different return value for same sig
float overloadA(out float f, int); float overloadA(out float f, int);
float overloadA(int i); float overloadA(int i);
vec2 overloadB(float, float); void overloadB(float, const in float) { }
vec2 overloadC(int, int); vec2 overloadC(int, int);
vec2 overloadC(int, float); vec2 overloadC(const in int, float);
vec2 overloadC(float, int); vec2 overloadC(float, int);
vec2 overloadC(vec2, vec2); vec2 overloadC(vec2, vec2);
vec3 overloadD(int, float); vec3 overloadD(int, float);
vec3 overloadD(float, int); vec3 overloadD(float, in int);
vec3 overloadE(float[2]); vec3 overloadE(float[2]);
vec3 overloadE(mat2 m); vec3 overloadE(mat2 m);
...@@ -119,3 +119,21 @@ void foo() ...@@ -119,3 +119,21 @@ void foo()
} }
varying vec4 gl_TexCoord[35]; // ERROR, size too big varying vec4 gl_TexCoord[35]; // ERROR, size too big
// tests for output conversions
void outFun(in float, out ivec2, in int, out float);
int outFunRet(in float, out int, const in int, out ivec4);
ivec2 outFunRet(in float, out ivec4, in int, out ivec4);
void foo2()
{
vec2 v2;
vec4 v4;
float f;
int i;
outFun(i, v2, i, f);
outFunRet(i, f, i, v4);
float ret = outFunRet(i, f, i, v4);
vec2 ret2 = outFunRet(i, v4, i, v4);
}
...@@ -94,20 +94,25 @@ ERROR: node is still EOpNull! ...@@ -94,20 +94,25 @@ ERROR: node is still EOpNull!
0:43 'gl_PointSize' (invariant gl_PointSize float) 0:43 'gl_PointSize' (invariant gl_PointSize float)
0:43 Constant: 0:43 Constant:
0:43 3.800000 0:43 3.800000
0:61 Function Definition: overloadB(f1;f1; (void)
0:61 Function Parameters:
0:61 '' (in float)
0:61 '' (const (read only) float)
0:78 Function Definition: foo( (void) 0:78 Function Definition: foo( (void)
0:78 Function Parameters: 0:78 Function Parameters:
0:? Sequence 0:? Sequence
0:83 Function Call: overloadB(f1;f1; (2-component vector of float) 0:83 Function Call: overloadB(f1;f1; (void)
0:83 'f' (float) 0:83 'f' (float)
0:83 'f' (float) 0:83 'f' (float)
0:84 Function Call: overloadB(f1;f1; (2-component vector of float) 0:84 Function Call: overloadB(f1;f1; (void)
0:84 'f' (float) 0:84 'f' (float)
0:84 Constant: 0:84 Constant:
0:84 2 (const int) 0:84 2.000000
0:85 Function Call: overloadB(f1;f1; (2-component vector of float) 0:85 Function Call: overloadB(f1;f1; (void)
0:85 Constant: 0:85 Constant:
0:85 1 (const int) 0:85 1.000000
0:85 'i' (int) 0:85 Convert int to float (float)
0:85 'i' (int)
0:87 Constant: 0:87 Constant:
0:87 0.000000 0:87 0.000000
0:88 Function Call: overloadC(i1;i1; (2-component vector of float) 0:88 Function Call: overloadC(i1;i1; (2-component vector of float)
...@@ -125,8 +130,8 @@ ERROR: node is still EOpNull! ...@@ -125,8 +130,8 @@ ERROR: node is still EOpNull!
0:90 0.000000 0:90 0.000000
0:91 Function Call: overloadC(vf2;vf2; (2-component vector of float) 0:91 Function Call: overloadC(vf2;vf2; (2-component vector of float)
0:91 Constant: 0:91 Constant:
0:91 1 (const int) 0:91 1.000000
0:91 1 (const int) 0:91 1.000000
0:91 Constant: 0:91 Constant:
0:91 2.000000 0:91 2.000000
0:91 2.000000 0:91 2.000000
...@@ -137,7 +142,8 @@ ERROR: node is still EOpNull! ...@@ -137,7 +142,8 @@ ERROR: node is still EOpNull!
0:94 'f' (float) 0:94 'f' (float)
0:94 'i' (int) 0:94 'i' (int)
0:95 Function Call: overloadD(f1;i1; (3-component vector of float) 0:95 Function Call: overloadD(f1;i1; (3-component vector of float)
0:95 'i' (int) 0:95 Convert int to float (float)
0:95 'i' (int)
0:95 'i' (int) 0:95 'i' (int)
0:98 Constant: 0:98 Constant:
0:98 0.000000 0:98 0.000000
...@@ -146,8 +152,8 @@ ERROR: node is still EOpNull! ...@@ -146,8 +152,8 @@ ERROR: node is still EOpNull!
0:101 Function Call: texture2D(s21;vf2; (4-component vector of float) 0:101 Function Call: texture2D(s21;vf2; (4-component vector of float)
0:101 's2D' (uniform sampler2D) 0:101 's2D' (uniform sampler2D)
0:101 Constant: 0:101 Constant:
0:101 0 (const int) 0:101 0.000000
0:101 0 (const int) 0:101 0.000000
0:102 clamp (4-component vector of float) 0:102 clamp (4-component vector of float)
0:102 'attv4' (in 4-component vector of float) 0:102 'attv4' (in 4-component vector of float)
0:102 Constant: 0:102 Constant:
...@@ -181,8 +187,8 @@ ERROR: node is still EOpNull! ...@@ -181,8 +187,8 @@ ERROR: node is still EOpNull!
0:111 0.000000 0:111 0.000000
0:112 Function Call: overloadE(vf2; (3-component vector of float) 0:112 Function Call: overloadE(vf2; (3-component vector of float)
0:112 Constant: 0:112 Constant:
0:112 1 (const int) 0:112 1.000000
0:112 1 (const int) 0:112 1.000000
0:115 Function Call: overloadE(f1[2]; (3-component vector of float) 0:115 Function Call: overloadE(f1[2]; (3-component vector of float)
0:115 'b' (2-element array of float) 0:115 'b' (2-element array of float)
0:117 Constant: 0:117 Constant:
...@@ -190,6 +196,82 @@ ERROR: node is still EOpNull! ...@@ -190,6 +196,82 @@ ERROR: node is still EOpNull!
0:118 Function Call: overloadF(i1; (3-component vector of float) 0:118 Function Call: overloadF(i1; (3-component vector of float)
0:118 Constant: 0:118 Constant:
0:118 1 (const int) 0:118 1 (const int)
0:128 Function Definition: foo2( (void)
0:128 Function Parameters:
0:? Sequence
0:135 Comma (void)
0:135 Function Call: outFun(f1;vi2;i1;f1; (void)
0:135 Convert int to float (float)
0:135 'i' (int)
0:135 'tempArg' (out 2-component vector of int)
0:135 'i' (int)
0:135 'f' (float)
0:135 move second child to first child (2-component vector of float)
0:135 'v2' (2-component vector of float)
0:135 Convert int to float (2-component vector of float)
0:135 'tempArg' (out 2-component vector of int)
0:136 Comma (int)
0:136 move second child to first child (int)
0:136 'tempReturn' (int)
0:136 Function Call: outFunRet(f1;i1;i1;vi4; (int)
0:136 Convert int to float (float)
0:136 'i' (int)
0:136 'tempArg' (out int)
0:136 'i' (int)
0:136 'tempArg' (out 4-component vector of int)
0:136 move second child to first child (float)
0:136 'f' (float)
0:136 Convert int to float (float)
0:136 'tempArg' (out int)
0:136 move second child to first child (4-component vector of float)
0:136 'v4' (4-component vector of float)
0:136 Convert int to float (4-component vector of float)
0:136 'tempArg' (out 4-component vector of int)
0:136 'tempReturn' (int)
0:137 Sequence
0:137 move second child to first child (float)
0:137 'ret' (float)
0:137 Convert int to float (float)
0:137 Comma (int)
0:137 move second child to first child (int)
0:137 'tempReturn' (int)
0:137 Function Call: outFunRet(f1;i1;i1;vi4; (int)
0:137 Convert int to float (float)
0:137 'i' (int)
0:137 'tempArg' (out int)
0:137 'i' (int)
0:137 'tempArg' (out 4-component vector of int)
0:137 move second child to first child (float)
0:137 'f' (float)
0:137 Convert int to float (float)
0:137 'tempArg' (out int)
0:137 move second child to first child (4-component vector of float)
0:137 'v4' (4-component vector of float)
0:137 Convert int to float (4-component vector of float)
0:137 'tempArg' (out 4-component vector of int)
0:137 'tempReturn' (int)
0:138 Sequence
0:138 move second child to first child (2-component vector of float)
0:138 'ret2' (2-component vector of float)
0:138 Convert int to float (2-component vector of float)
0:138 Comma (2-component vector of int)
0:138 move second child to first child (2-component vector of int)
0:138 'tempReturn' (2-component vector of int)
0:138 Function Call: outFunRet(f1;vi4;i1;vi4; (2-component vector of int)
0:138 Convert int to float (float)
0:138 'i' (int)
0:138 'tempArg' (out 4-component vector of int)
0:138 'i' (int)
0:138 'tempArg' (out 4-component vector of int)
0:138 move second child to first child (4-component vector of float)
0:138 'v4' (4-component vector of float)
0:138 Convert int to float (4-component vector of float)
0:138 'tempArg' (out 4-component vector of int)
0:138 move second child to first child (4-component vector of float)
0:138 'v4' (4-component vector of float)
0:138 Convert int to float (4-component vector of float)
0:138 'tempArg' (out 4-component vector of int)
0:138 'tempReturn' (2-component vector of int)
0:? Linker Objects 0:? Linker Objects
0:? 'i' (in 4-component vector of float) 0:? 'i' (in 4-component vector of float)
0:? 'o' (smooth out 4-component vector of float) 0:? 'o' (smooth out 4-component vector of float)
......
...@@ -74,8 +74,7 @@ enum TStorageQualifier { ...@@ -74,8 +74,7 @@ enum TStorageQualifier {
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
EvqInOut, EvqInOut,
EvqConstReadOnly, // input; also other read-only types having neither a constant value nor constant-value semantics
EvqConstReadOnly, // read-only types, not having a constant value or constant-value semantics
// built-ins read by vertex shader // built-ins read by vertex shader
EvqVertexId, EvqVertexId,
......
...@@ -238,9 +238,15 @@ class TQualifier { ...@@ -238,9 +238,15 @@ class TQualifier {
public: public:
void clear() void clear()
{ {
storage = EvqTemporary;
precision = EpqNone; precision = EpqNone;
invariant = false; invariant = false;
makeTemporary();
}
// drop qualifiers that don't belong in a temporary variable
void makeTemporary()
{
storage = EvqTemporary;
centroid = false; centroid = false;
smooth = false; smooth = false;
flat = false; flat = false;
...@@ -255,6 +261,7 @@ public: ...@@ -255,6 +261,7 @@ public:
writeonly = false; writeonly = false;
clearLayout(); clearLayout();
} }
TStorageQualifier storage : 6; TStorageQualifier storage : 6;
TPrecisionQualifier precision : 3; TPrecisionQualifier precision : 3;
bool invariant : 1; bool invariant : 1;
...@@ -314,6 +321,29 @@ public: ...@@ -314,6 +321,29 @@ public:
} }
} }
bool isParamInput() const
{
switch (storage) {
case EvqIn:
case EvqInOut:
case EvqConstReadOnly:
return true;
default:
return false;
}
}
bool isParamOutput() const
{
switch (storage) {
case EvqOut:
case EvqInOut:
return true;
default:
return false;
}
}
bool isUniform() const bool isUniform() const
{ {
switch (storage) { switch (storage) {
......
...@@ -247,7 +247,7 @@ enum TOperator { ...@@ -247,7 +247,7 @@ enum TOperator {
// //
EOpConstructGuardStart, EOpConstructGuardStart,
EOpConstructInt, EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
EOpConstructUint, EOpConstructUint,
EOpConstructBool, EOpConstructBool,
EOpConstructFloat, EOpConstructFloat,
......
...@@ -67,6 +67,11 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType ...@@ -67,6 +67,11 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
return node; return node;
} }
TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, TSourceLoc loc)
{
return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), loc);
}
// //
// Connect two nodes with a new parent that does a binary operation on the nodes. // Connect two nodes with a new parent that does a binary operation on the nodes.
// //
...@@ -363,14 +368,16 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o ...@@ -363,14 +368,16 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
} }
// //
// Convert one type to another. // Convert the node's type to the given type, as allowed by the operation involved 'op'.
// For implicit conversions, 'op' is not the requested conversion, it is the explicit
// operation requiring the implicit conversion.
// //
// Returns the node representing the conversion, which could be the same // Returns the node representing the conversion, which could be the same
// node passed in if no conversion was needed. // node passed in if no conversion was needed.
// //
// Return 0 if a conversion can't be done. // Return 0 if a conversion can't be done.
// //
TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const
{ {
// //
// Does the base type allow operation? // Does the base type allow operation?
...@@ -490,88 +497,86 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt ...@@ -490,88 +497,86 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
return 0; return 0;
} }
if (node->getAsConstantUnion()) { if (node->getAsConstantUnion())
return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
} else {
//
// Add a new newNode for the conversion.
//
TIntermUnary* newNode = 0;
TOperator newOp = EOpNull; //
// Add a new newNode for the conversion.
//
TIntermUnary* newNode = 0;
// This is 'mechanism' here, it does any conversion told. The policy comes TOperator newOp = EOpNull;
// from the shader or the above code.
switch (promoteTo) { // This is 'mechanism' here, it does any conversion told. The policy comes
case EbtDouble: // from the shader or the above code.
//switch (node->getBasicType()) { switch (promoteTo) {
//case EbtInt: newOp = EOpConvIntToDouble; break; case EbtDouble:
//case EbtUint: newOp = EOpConvUintToDouble; break; //switch (node->getBasicType()) {
//case EbtBool: newOp = EOpConvBoolToDouble; break; //case EbtInt: newOp = EOpConvIntToDouble; break;
//case EbtFloat: newOp = EOpConvFloatToDouble; break; //case EbtUint: newOp = EOpConvUintToDouble; break;
//default: //case EbtBool: newOp = EOpConvBoolToDouble; break;
return 0; //case EbtFloat: newOp = EOpConvFloatToDouble; break;
//} //default:
break; return 0;
case EbtFloat: //}
switch (node->getBasicType()) { break;
case EbtInt: newOp = EOpConvIntToFloat; break; case EbtFloat:
case EbtUint: newOp = EOpConvUintToFloat; break; switch (node->getBasicType()) {
case EbtBool: newOp = EOpConvBoolToFloat; break; case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtDouble: newOp = EOpConvDoubleToFloat; break; case EbtUint: newOp = EOpConvUintToFloat; break;
default: case EbtBool: newOp = EOpConvBoolToFloat; break;
return 0; case EbtDouble: newOp = EOpConvDoubleToFloat; break;
} default:
break; return 0;
case EbtBool: }
switch (node->getBasicType()) { break;
case EbtInt: newOp = EOpConvIntToBool; break; case EbtBool:
case EbtUint: newOp = EOpConvUintToBool; break; switch (node->getBasicType()) {
case EbtFloat: newOp = EOpConvFloatToBool; break; case EbtInt: newOp = EOpConvIntToBool; break;
case EbtDouble: newOp = EOpConvDoubleToBool; break; case EbtUint: newOp = EOpConvUintToBool; break;
default: case EbtFloat: newOp = EOpConvFloatToBool; break;
return 0; case EbtDouble: newOp = EOpConvDoubleToBool; break;
} default:
break; return 0;
case EbtInt: }
switch (node->getBasicType()) { break;
case EbtUint: newOp = EOpConvUintToInt; break; case EbtInt:
case EbtBool: newOp = EOpConvBoolToInt; break; switch (node->getBasicType()) {
case EbtFloat: newOp = EOpConvFloatToInt; break; case EbtUint: newOp = EOpConvUintToInt; break;
case EbtDouble: newOp = EOpConvDoubleToInt; break; case EbtBool: newOp = EOpConvBoolToInt; break;
default: case EbtFloat: newOp = EOpConvFloatToInt; break;
return 0; case EbtDouble: newOp = EOpConvDoubleToInt; break;
} default:
break; return 0;
case EbtUint: }
switch (node->getBasicType()) { break;
case EbtInt: newOp = EOpConvIntToUint; break; case EbtUint:
case EbtBool: newOp = EOpConvBoolToUint; break; switch (node->getBasicType()) {
case EbtFloat: newOp = EOpConvFloatToUint; break; case EbtInt: newOp = EOpConvIntToUint; break;
case EbtDouble: newOp = EOpConvDoubleToUint; break; case EbtBool: newOp = EOpConvBoolToUint; break;
default: case EbtFloat: newOp = EOpConvFloatToUint; break;
return 0; case EbtDouble: newOp = EOpConvDoubleToUint; break;
} default:
break;
default:
return 0; return 0;
} }
break;
default:
return 0;
}
TType type(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
newNode = new TIntermUnary(newOp, type); newNode = new TIntermUnary(newOp, newType);
newNode->setLoc(node->getLoc()); newNode->setLoc(node->getLoc());
newNode->setOperand(node); newNode->setOperand(node);
return newNode; return newNode;
}
} }
// //
// See if the 'from' type is allowed to be implicitly converted to the // See if the 'from' type is allowed to be implicitly converted to the
// 'to' type. This is not about vector/array/struct, only about basic type. // 'to' type. This is not about vector/array/struct, only about basic type.
// //
bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) const
{ {
if (profile == EEsProfile || version == 110) if (profile == EEsProfile || version == 110)
return false; return false;
...@@ -713,8 +718,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T ...@@ -713,8 +718,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
TIntermTyped *commaAggregate = growAggregate(left, right, loc); TIntermTyped *commaAggregate = growAggregate(left, right, loc);
commaAggregate->getAsAggregate()->setOperator(EOpComma); commaAggregate->getAsAggregate()->setOperator(EOpComma);
commaAggregate->setType(right->getType()); commaAggregate->setType(right->getType());
commaAggregate->getWritableType().getQualifier().storage = EvqTemporary; commaAggregate->getWritableType().getQualifier().makeTemporary();
commaAggregate->getWritableType().getQualifier().precision = right->getType().getQualifier().precision;
return commaAggregate; return commaAggregate;
} }
...@@ -782,7 +786,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true ...@@ -782,7 +786,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Returns the constant union node created. // Returns the constant union node created.
// //
TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc, bool literal) TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc, bool literal) const
{ {
TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
node->setLoc(loc); node->setLoc(loc);
...@@ -1028,7 +1032,7 @@ bool TIntermUnary::promote() ...@@ -1028,7 +1032,7 @@ bool TIntermUnary::promote()
} }
setType(operand->getType()); setType(operand->getType());
getWritableType().getQualifier().storage = EvqTemporary; getWritableType().getQualifier().makeTemporary();
return true; return true;
} }
...@@ -1412,7 +1416,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) ...@@ -1412,7 +1416,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
} }
} }
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const
{ {
const TConstUnionArray& rightUnionArray = node->getConstArray(); const TConstUnionArray& rightUnionArray = node->getConstArray();
int size = node->getType().computeNumComponents(); int size = node->getType().computeNumComponents();
......
...@@ -98,8 +98,9 @@ public: ...@@ -98,8 +98,9 @@ public:
TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&); TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*); TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*);
TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*); TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*);
TIntermTyped* handleArgumentConversions(const TFunction&, TIntermAggregate&) const;
void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&); void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&);
TFunction* handleConstructorCall(TSourceLoc, TPublicType&); TFunction* handleConstructorCall(TSourceLoc, const TPublicType&);
bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&); bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&);
void assignError(TSourceLoc, const char* op, TString left, TString right); void assignError(TSourceLoc, const char* op, TString left, TString right);
...@@ -205,11 +206,12 @@ public: ...@@ -205,11 +206,12 @@ public:
protected: protected:
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type); void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
void inheritGlobalDefaults(TQualifier& dst) const; void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration); TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration); void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
TIntermNode* executeInitializer(TSourceLoc, TString& identifier, TIntermTyped* initializer, TVariable* variable); TIntermNode* executeInitializer(TSourceLoc, TString& identifier, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(TSourceLoc, const TType&, TIntermTyped* initializer); TIntermTyped* convertInitializerList(TSourceLoc, const TType&, TIntermTyped* initializer);
TOperator mapTypeToConstructorOp(const TType&); TOperator mapTypeToConstructorOp(const TType&) const;
void finalErrorCheck(); void finalErrorCheck();
public: public:
......
...@@ -502,6 +502,12 @@ public: ...@@ -502,6 +502,12 @@ public:
table.pop_back(); table.pop_back();
} }
//
// Insert a visible symbol into the symbol table so it can
// be found later by name.
//
// Returns false if the was a name collision.
//
bool insert(TSymbol& symbol) bool insert(TSymbol& symbol)
{ {
symbol.setUniqueId(++uniqueId); symbol.setUniqueId(++uniqueId);
...@@ -524,6 +530,17 @@ public: ...@@ -524,6 +530,17 @@ public:
} }
// //
// To allocate an internal temporary, which will need to be uniquely
// identified by the consumer of the AST, but never need to
// found by doing a symbol table search by name, hence allowed an
// arbitrary name in the symbol with no worry of collision.
//
void makeInternalVariable(TSymbol& symbol)
{
symbol.setUniqueId(++uniqueId);
}
//
// Copy a variable or anonymous member's structure from a shared level up // Copy a variable or anonymous member's structure from a shared level up
// to the current level, so it can be modified without impacting other users // to the current level, so it can be modified without impacting other users
// of the shared table. // of the shared table.
......
...@@ -102,6 +102,7 @@ struct TXfbBuffer { ...@@ -102,6 +102,7 @@ struct TXfbBuffer {
class TSymbolTable; class TSymbolTable;
class TSymbol; class TSymbol;
class TVariable;
// //
// Set of helper functions to help parse and build the tree. // Set of helper functions to help parse and build the tree.
...@@ -133,13 +134,14 @@ public: ...@@ -133,13 +134,14 @@ public:
bool isRecursive() const { return recursive; } bool isRecursive() const { return recursive; }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc); TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); TIntermSymbol* addSymbol(const TVariable&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc); TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc);
TIntermTyped* addBuiltInFunctionCall(TSourceLoc line, TOperator, bool unary, TIntermNode*, const TType& returnType); TIntermTyped* addBuiltInFunctionCall(TSourceLoc line, TOperator, bool unary, TIntermNode*, const TType& returnType);
bool canImplicitlyPromote(TBasicType from, TBasicType to); bool canImplicitlyPromote(TBasicType from, TBasicType to) const;
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
TIntermAggregate* makeAggregate(TIntermNode* node); TIntermAggregate* makeAggregate(TIntermNode* node);
...@@ -150,8 +152,8 @@ public: ...@@ -150,8 +152,8 @@ public:
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc); TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc); TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false); TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ; TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc); TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
TIntermBranch* addBranch(TOperator, TSourceLoc); TIntermBranch* addBranch(TOperator, TSourceLoc);
......
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