Expand implicit argument conversions to also include handling built-in function calls.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@26080 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2014-03-26 03:17:31 +00:00
parent 0af1e7c608
commit f5dd2f5c7c
10 changed files with 374 additions and 227 deletions

View File

@ -136,4 +136,5 @@ void foo2()
outFunRet(i, f, i, v4);
float ret = outFunRet(i, f, i, v4);
vec2 ret2 = outFunRet(i, v4, i, v4);
bool b = any(lessThan(v4, attv4)); // tests aggregate arg to unary built-in
}

View File

@ -26,3 +26,9 @@ layout(location=3) in vec4 vl; // ERROR
#extension GL_ARB_separate_shader_objects : enable
layout(location=4) in vec4 vl2;
void foo()
{
vec2 r1 = modf(v.xy, v.zw); // ERROR, v.zw not l-value
vec2 r2 = modf(o.xy, o.zw);
}

View File

@ -56,3 +56,9 @@ void foo23()
patch in vec4 patchIn; // ERROR
patch out vec4 patchOut; // ERROR
void foo24()
{
dvec3 df, di;
df = modf(outp.xyz, di);
}

View File

@ -148,7 +148,7 @@ ERROR: node is still EOpNull!
0:98 Constant:
0:98 0.000000
0:100 Constant:
0:100 0.000000
0:100 0.841471
0:101 Function Call: texture2D(s21;vf2; (4-component vector of float)
0:101 's2D' (uniform sampler2D)
0:101 Constant:
@ -157,16 +157,17 @@ ERROR: node is still EOpNull!
0:102 clamp (4-component vector of float)
0:102 'attv4' (in 4-component vector of float)
0:102 Constant:
0:102 0 (const int)
0:102 0.000000
0:102 Constant:
0:102 1 (const int)
0:102 1.000000
0:103 clamp (4-component vector of float)
0:103 Convert float to int (4-component vector of int)
0:103 'attv4' (in 4-component vector of float)
0:103 Convert int to float (4-component vector of float)
0:103 Convert float to int (4-component vector of int)
0:103 'attv4' (in 4-component vector of float)
0:103 Constant:
0:103 0 (const int)
0:103 0.000000
0:103 Constant:
0:103 1 (const int)
0:103 1.000000
0:106 Constant:
0:106 0.000000
0:107 Constant:
@ -272,6 +273,13 @@ ERROR: node is still EOpNull!
0:138 Convert int to float (4-component vector of float)
0:138 'tempArg' (4-component vector of int)
0:138 'tempReturn' (2-component vector of int)
0:139 Sequence
0:139 move second child to first child (bool)
0:139 'b' (bool)
0:139 any (bool)
0:139 Compare Less Than (4-component vector of bool)
0:139 'v4' (4-component vector of float)
0:139 'attv4' (in 4-component vector of float)
0:? Linker Objects
0:? 'i' (in 4-component vector of float)
0:? 'o' (smooth out 4-component vector of float)

View File

@ -5,7 +5,9 @@ ERROR: 0:17: '#error' : GL_ES is not set
ERROR: 0:20: 'fragment-shader struct input' : not supported for this version or the enabled extensions
ERROR: 0:24: 'location' : not supported for this version or the enabled extensions
ERROR: 0:24: 'location qualifier on input' : not supported for this version or the enabled extensions
ERROR: 4 compilation errors. No code generated.
ERROR: 0:32: 'assign' : l-value required "v" (can't modify shader input)
ERROR: 0:32: 'out' : Non-L-value cannot be passed for 'out' or 'inout' parameters.
ERROR: 6 compilation errors. No code generated.
ERROR: node is still EOpNull!
@ -24,6 +26,45 @@ ERROR: node is still EOpNull!
0:22 'patch' (float)
0:22 Constant:
0:22 3.100000
0:30 Function Definition: foo( (void)
0:30 Function Parameters:
0:32 Sequence
0:32 Sequence
0:32 move second child to first child (2-component vector of float)
0:32 'r1' (2-component vector of float)
0:32 modf (2-component vector of float)
0:32 vector swizzle (2-component vector of float)
0:32 'v' (smooth in 4-component vector of float)
0:32 Sequence
0:32 Constant:
0:32 0 (const int)
0:32 Constant:
0:32 1 (const int)
0:32 vector swizzle (2-component vector of float)
0:32 'v' (smooth in 4-component vector of float)
0:32 Sequence
0:32 Constant:
0:32 2 (const int)
0:32 Constant:
0:32 3 (const int)
0:33 Sequence
0:33 move second child to first child (2-component vector of float)
0:33 'r2' (2-component vector of float)
0:33 modf (2-component vector of float)
0:33 vector swizzle (2-component vector of float)
0:33 'o' (out 4-component vector of float)
0:33 Sequence
0:33 Constant:
0:33 0 (const int)
0:33 Constant:
0:33 1 (const int)
0:33 vector swizzle (2-component vector of float)
0:33 'o' (out 4-component vector of float)
0:33 Sequence
0:33 Constant:
0:33 2 (const int)
0:33 Constant:
0:33 3 (const int)
0:? Linker Objects
0:? 'v' (smooth in 4-component vector of float)
0:? 'i' (smooth in 4-component vector of float)

View File

@ -190,6 +190,31 @@ ERROR: node is still EOpNull!
0:54 Constant:
0:54 -10 (const int)
0:54 20 (const int)
0:60 Function Definition: foo24( (void)
0:60 Function Parameters:
0:? Sequence
0:63 move second child to first child (3-component vector of double)
0:63 'df' (3-component vector of double)
0:63 Convert float to double (3-component vector of double)
0:63 Comma (3-component vector of float)
0:63 move second child to first child (3-component vector of float)
0:63 'tempReturn' (3-component vector of float)
0:63 modf (3-component vector of float)
0:63 vector swizzle (3-component vector of float)
0:63 'outp' (out 4-component vector of float)
0:63 Sequence
0:63 Constant:
0:63 0 (const int)
0:63 Constant:
0:63 1 (const int)
0:63 Constant:
0:63 2 (const int)
0:63 'tempArg' (3-component vector of float)
0:63 move second child to first child (3-component vector of double)
0:63 'di' (3-component vector of double)
0:63 Convert float to double (3-component vector of double)
0:63 'tempArg' (3-component vector of float)
0:63 'tempReturn' (3-component vector of float)
0:? Linker Objects
0:? 'c2D' (smooth in 2-component vector of float)
0:? 'i' (flat in int)

View File

@ -2,170 +2,192 @@
Warning, version 400 is not yet complete; some version-specific features are present, but many are missing.
0:? Sequence
0:3 Function Definition: foo(i1;i1;i1;i1;i1;i1; (int)
0:3 Function Parameters:
0:3 'a' (in int)
0:3 'b' (const (read only) int)
0:3 'c' (in int)
0:3 'd' (const (read only) int)
0:3 'e' (out int)
0:3 'f' (inout int)
0:5 Sequence
0:5 Sequence
0:5 move second child to first child (int)
0:5 'sum' (int)
0:5 add (int)
0:5 add (int)
0:5 add (int)
0:5 add (int)
0:5 'a' (in int)
0:5 'b' (const (read only) int)
0:5 'c' (in int)
0:5 'd' (const (read only) int)
0:5 'f' (inout int)
0:8 multiply second child into first child (int)
0:8 'a' (in int)
0:8 Constant:
0:8 64 (const int)
0:5 Function Definition: foo(i1;i1;i1;i1;i1;i1; (int)
0:5 Function Parameters:
0:5 'a' (in int)
0:5 'b' (const (read only) int)
0:5 'c' (in int)
0:5 'd' (const (read only) int)
0:5 'e' (out int)
0:5 'f' (inout int)
0:7 Sequence
0:7 Sequence
0:7 move second child to first child (int)
0:7 'sum' (int)
0:7 add (int)
0:7 add (int)
0:7 add (int)
0:7 add (int)
0:7 'a' (in int)
0:7 'b' (const (read only) int)
0:7 'c' (in int)
0:7 'd' (const (read only) int)
0:7 'f' (inout int)
0:10 multiply second child into first child (int)
0:10 'c' (in int)
0:10 'a' (in int)
0:10 Constant:
0:10 64 (const int)
0:12 move second child to first child (int)
0:12 'e' (out int)
0:12 multiply second child into first child (int)
0:12 'c' (in int)
0:12 Constant:
0:12 1024 (const int)
0:13 multiply second child into first child (int)
0:13 'f' (inout int)
0:13 Constant:
0:13 64 (const int)
0:15 add second child into first child (int)
0:15 'sum' (int)
0:15 add (int)
0:15 add (int)
0:15 add (int)
0:15 add (int)
0:15 add (int)
0:15 'a' (in int)
0:15 component-wise multiply (int)
0:15 Constant:
0:15 64 (const int)
0:15 'b' (const (read only) int)
0:15 'c' (in int)
0:15 component-wise multiply (int)
0:15 Constant:
0:15 64 (const int)
0:15 'd' (const (read only) int)
0:15 'e' (out int)
0:15 'f' (inout int)
0:18 Branch: Return with expression
0:18 'sum' (int)
0:21 Function Definition: foo2(f1;vf3;i1; (int)
0:21 Function Parameters:
0:21 'a' (in float)
0:21 'b' (in 3-component vector of float)
0:21 'r' (out int)
0:23 Sequence
0:23 move second child to first child (int)
0:23 'r' (out int)
0:23 Convert float to int (int)
0:23 component-wise multiply (float)
0:23 Constant:
0:23 3.000000
0:23 'a' (in float)
0:24 Branch: Return with expression
0:24 Convert float to int (int)
0:24 component-wise multiply (float)
0:24 Constant:
0:24 5.000000
0:24 direct index (float)
0:24 'b' (in 3-component vector of float)
0:24 Constant:
0:24 1 (const int)
0:27 Function Definition: main( (void)
0:27 Function Parameters:
0:12 64 (const int)
0:14 move second child to first child (int)
0:14 'e' (out int)
0:14 Constant:
0:14 1024 (const int)
0:15 multiply second child into first child (int)
0:15 'f' (inout int)
0:15 Constant:
0:15 64 (const int)
0:17 add second child into first child (int)
0:17 'sum' (int)
0:17 add (int)
0:17 add (int)
0:17 add (int)
0:17 add (int)
0:17 add (int)
0:17 'a' (in int)
0:17 component-wise multiply (int)
0:17 Constant:
0:17 64 (const int)
0:17 'b' (const (read only) int)
0:17 'c' (in int)
0:17 component-wise multiply (int)
0:17 Constant:
0:17 64 (const int)
0:17 'd' (const (read only) int)
0:17 'e' (out int)
0:17 'f' (inout int)
0:20 Branch: Return with expression
0:20 'sum' (int)
0:23 Function Definition: foo2(f1;vf3;i1; (int)
0:23 Function Parameters:
0:23 'a' (in float)
0:23 'b' (in 3-component vector of float)
0:23 'r' (out int)
0:25 Sequence
0:25 move second child to first child (int)
0:25 'r' (out int)
0:25 Convert float to int (int)
0:25 component-wise multiply (float)
0:25 Constant:
0:25 3.000000
0:25 'a' (in float)
0:26 Branch: Return with expression
0:26 Convert float to int (int)
0:26 component-wise multiply (float)
0:26 Constant:
0:26 5.000000
0:26 direct index (float)
0:26 'b' (in 3-component vector of float)
0:26 Constant:
0:26 1 (const int)
0:29 Function Definition: foo3( (int)
0:29 Function Parameters:
0:31 Sequence
0:31 Test condition and select (void)
0:31 Condition
0:31 Compare Greater Than (bool)
0:31 'u' (uniform float)
0:31 Constant:
0:31 3.200000
0:31 true case
0:32 Sequence
0:32 Branch: Kill
0:33 Branch: Return with expression
0:33 Constant:
0:33 1000000 (const int)
0:36 Branch: Return with expression
0:36 Constant:
0:36 2000000 (const int)
0:39 Function Definition: main( (void)
0:39 Function Parameters:
0:? Sequence
0:30 Sequence
0:30 move second child to first child (int)
0:30 't' (int)
0:30 Constant:
0:30 2 (const int)
0:34 move second child to first child (int)
0:34 direct index (int)
0:34 t: direct index for structure (4-component vector of int)
0:34 'f' (structure{4-component vector of int t})
0:34 Constant:
0:34 0 (const int)
0:34 Constant:
0:34 1 (const int)
0:34 Constant:
0:34 32 (const int)
0:37 Sequence
0:37 move second child to first child (int)
0:37 'color' (int)
0:37 Function Call: foo(i1;i1;i1;i1;i1;i1; (int)
0:37 Constant:
0:37 1 (const int)
0:37 Constant:
0:37 2 (const int)
0:37 add (int)
0:37 't' (int)
0:37 't' (int)
0:37 Constant:
0:37 8 (const int)
0:37 'e' (int)
0:37 direct index (int)
0:37 t: direct index for structure (4-component vector of int)
0:37 'f' (structure{4-component vector of int t})
0:37 Constant:
0:37 0 (const int)
0:37 Constant:
0:37 1 (const int)
0:39 add second child into first child (int)
0:39 'color' (int)
0:39 component-wise multiply (int)
0:39 Constant:
0:39 128 (const int)
0:39 add (int)
0:39 'e' (int)
0:39 direct index (int)
0:39 t: direct index for structure (4-component vector of int)
0:39 'f' (structure{4-component vector of int t})
0:39 Constant:
0:39 0 (const int)
0:39 Constant:
0:39 1 (const int)
0:45 move second child to first child (float)
0:45 'ret' (float)
0:45 Convert int to float (float)
0:45 Comma (int)
0:45 move second child to first child (int)
0:45 'tempReturn' (int)
0:45 Function Call: foo2(f1;vf3;i1; (int)
0:45 Constant:
0:45 4.000000
0:45 Constant:
0:45 1.000000
0:45 2.000000
0:45 3.000000
0:45 'tempArg' (int)
0:45 move second child to first child (float)
0:45 'arg' (float)
0:45 Convert int to float (float)
0:45 'tempArg' (int)
0:45 'tempReturn' (int)
0:46 add second child into first child (int)
0:46 'color' (int)
0:46 Convert float to int (int)
0:46 add (float)
0:46 'ret' (float)
0:46 'arg' (float)
0:48 move second child to first child (4-component vector of float)
0:48 'gl_FragColor' (fragColor 4-component vector of float)
0:48 Construct vec4 (4-component vector of float)
0:48 Convert int to float (float)
0:48 'color' (int)
0:42 Sequence
0:42 move second child to first child (int)
0:42 't' (int)
0:42 Constant:
0:42 2 (const int)
0:46 move second child to first child (int)
0:46 direct index (int)
0:46 t: direct index for structure (4-component vector of int)
0:46 'f' (structure{4-component vector of int t})
0:46 Constant:
0:46 0 (const int)
0:46 Constant:
0:46 1 (const int)
0:46 Constant:
0:46 32 (const int)
0:49 Sequence
0:49 move second child to first child (int)
0:49 'color' (int)
0:49 Function Call: foo(i1;i1;i1;i1;i1;i1; (int)
0:49 Constant:
0:49 1 (const int)
0:49 Constant:
0:49 2 (const int)
0:49 add (int)
0:49 't' (int)
0:49 't' (int)
0:49 Constant:
0:49 8 (const int)
0:49 'e' (int)
0:49 direct index (int)
0:49 t: direct index for structure (4-component vector of int)
0:49 'f' (structure{4-component vector of int t})
0:49 Constant:
0:49 0 (const int)
0:49 Constant:
0:49 1 (const int)
0:51 add second child into first child (int)
0:51 'color' (int)
0:51 component-wise multiply (int)
0:51 Constant:
0:51 128 (const int)
0:51 add (int)
0:51 'e' (int)
0:51 direct index (int)
0:51 t: direct index for structure (4-component vector of int)
0:51 'f' (structure{4-component vector of int t})
0:51 Constant:
0:51 0 (const int)
0:51 Constant:
0:51 1 (const int)
0:57 move second child to first child (float)
0:57 'ret' (float)
0:57 Convert int to float (float)
0:57 Comma (int)
0:57 move second child to first child (int)
0:57 'tempReturn' (int)
0:57 Function Call: foo2(f1;vf3;i1; (int)
0:57 Constant:
0:57 4.000000
0:57 Constant:
0:57 1.000000
0:57 2.000000
0:57 3.000000
0:57 'tempArg' (int)
0:57 move second child to first child (float)
0:57 'arg' (float)
0:57 Convert int to float (float)
0:57 'tempArg' (int)
0:57 'tempReturn' (int)
0:58 add second child into first child (int)
0:58 'color' (int)
0:58 Convert float to int (int)
0:58 add (float)
0:58 'ret' (float)
0:58 'arg' (float)
0:60 add second child into first child (int)
0:60 'color' (int)
0:60 Function Call: foo3( (int)
0:62 move second child to first child (4-component vector of float)
0:62 'gl_FragColor' (fragColor 4-component vector of float)
0:62 Construct vec4 (4-component vector of float)
0:62 Convert int to float (float)
0:62 'color' (int)
0:? Linker Objects
0:? 'u' (uniform float)
Linked fragment stage:

View File

@ -511,14 +511,14 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// from the shader or the above code.
switch (promoteTo) {
case EbtDouble:
//switch (node->getBasicType()) {
//case EbtInt: newOp = EOpConvIntToDouble; break;
//case EbtUint: newOp = EOpConvUintToDouble; break;
//case EbtBool: newOp = EOpConvBoolToDouble; break;
//case EbtFloat: newOp = EOpConvFloatToDouble; break;
//default:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToDouble; break;
case EbtUint: newOp = EOpConvUintToDouble; break;
case EbtBool: newOp = EOpConvBoolToDouble; break;
case EbtFloat: newOp = EOpConvFloatToDouble; break;
default:
return 0;
//}
}
break;
case EbtFloat:
switch (node->getBasicType()) {

View File

@ -914,13 +914,13 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunct
// - user function
// - subroutine call (not implemented yet)
//
TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* function, TIntermNode* intermNode)
TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* function, TIntermNode* arguments)
{
TIntermTyped* result = 0;
TOperator op = function->getBuiltInOp();
if (op == EOpArrayLength)
result = handleLengthMethod(loc, function, intermNode);
result = handleLengthMethod(loc, function, arguments);
else if (op != EOpNull) {
//
// Then this should be a constructor.
@ -928,11 +928,11 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct
// Their parameters will be verified algorithmically.
//
TType type(EbtVoid); // use this to get the type back
if (! constructorError(loc, intermNode, *function, op, type)) {
if (! constructorError(loc, arguments, *function, op, type)) {
//
// It's a constructor, of type 'type'.
//
result = addConstructor(loc, intermNode, type, op);
result = addConstructor(loc, arguments, type, op);
if (result == 0)
error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
}
@ -944,26 +944,46 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct
bool builtIn;
fnCandidate = findFunction(loc, *function, builtIn);
if (fnCandidate) {
// Error check for function requiring specific extensions present.
// This is a declared function that might map to
// - a built-in operator,
// - a built-in function not mapped to an operator, or
// - a user function.
// Error check for a function requiring specific extensions present.
if (builtIn && fnCandidate->getNumExtensions())
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
//
// A declared function. But, it might still map to a built-in
// operation.
//
if (arguments) {
// Make sure storage qualifications work for these arguments.
TIntermAggregate* aggregate = arguments->getAsAggregate();
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
if (qual == EvqOut || qual == EvqInOut) {
// At this early point there is a slight ambiguity between whether an aggregate 'arguments'
// is the single argument itself or its children are the arguments. Only one argument
// means take 'arguments' itself as the one argument.
TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments);
if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
}
}
// Convert 'in' arguments
addInputArgumentConversions(*fnCandidate, arguments); // arguments may be modified if it's just a single argument node
}
op = fnCandidate->getBuiltInOp();
if (builtIn && op != EOpNull) {
// A function call mapped to a built-in operation.
result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, intermNode, fnCandidate->getType());
result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, arguments, fnCandidate->getType());
if (result == 0) {
error(intermNode->getLoc(), " wrong operand type", "Internal Error",
error(arguments->getLoc(), " wrong operand type", "Internal Error",
"built in unary operator function. Type: %s",
static_cast<TIntermTyped*>(intermNode)->getCompleteString().c_str());
static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
}
} else {
// This is a function call not mapped to built-in operation
result = intermediate.setAggregateOperator(intermNode, EOpFunctionCall, fnCandidate->getType(), loc);
// This is a function call not mapped to built-in operator, but it could still be a built-in function
result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc);
TIntermAggregate* call = result->getAsAggregate();
call->setName(fnCandidate->getMangledName());
@ -975,23 +995,21 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct
intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
}
// Make sure storage qualifications work for these arguments.
TStorageQualifier qual;
TQualifierList& qualifierList = call->getQualifierList();
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
qual = (*fnCandidate)[i].type->getQualifier().storage;
if (qual == EvqOut || qual == EvqInOut) {
if (lValueErrorCheck(call->getLoc(), "assign", call->getSequence()[i]->getAsTyped()))
error(intermNode->getLoc(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
}
qualifierList.push_back(qual);
}
result = handleArgumentConversions(*fnCandidate, *call);
if (builtIn)
nonOpBuiltInCheck(loc, *fnCandidate, *call);
}
// Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore.
// Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
// Also, build the qualifier list for user function calls, which are always called with an aggregate.
if (result->getAsAggregate()) {
TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList();
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage;
qualifierList.push_back(qual);
}
result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
}
}
}
@ -1045,14 +1063,40 @@ TIntermTyped* TParseContext::handleLengthMethod(TSourceLoc loc, TFunction* funct
}
//
// Add any needed implicit conversions for function-call arguments. This is
// straightforward for input parameters, but output parameters need to
// a different tree topology, complicated further by whether the function
// has a return value. Create the new subtree, as neeeded.
// Add any needed implicit conversions for function-call arguments to input parameters.
//
void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
{
TIntermAggregate* aggregate = arguments->getAsAggregate();
// Process each argument's conversion
for (int i = 0; i < function.getParamCount(); ++i) {
// At this early point there is a slight ambiguity between whether an aggregate 'arguments'
// is the single argument itself or its children are the arguments. Only one argument
// means take 'arguments' itself as the one argument.
TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
if (*function[i].type != arg->getType()) {
if (function[i].type->getQualifier().isParamInput()) {
// In-qualified arguments just need an extra node added above the argument to
// convert to the correct type.
arg = intermediate.addConversion(EOpAssign, *function[i].type, arg);
if (aggregate)
aggregate->getSequence()[i] = arg;
else
arguments = arg;
}
}
}
}
//
// Add any needed implicit output conversions for function-call arguments. This
// can require a new tree topology, complicated further by whether the function
// has a return value.
//
// Returns a node of a subtree that evaluates to the return value of the function.
//
TIntermTyped* TParseContext::handleArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
{
TIntermSequence& arguments = intermNode.getSequence();
@ -1065,6 +1109,9 @@ TIntermTyped* TParseContext::handleArgumentConversions(const TFunction& function
}
}
if (! outputConversions)
return &intermNode;
// Setup for the new tree, if needed:
//
// Output conversions need a different tree topology.
@ -1075,26 +1122,20 @@ TIntermTyped* TParseContext::handleArgumentConversions(const TFunction& function
// Where the "tempArg" type needs no conversion as an argument, but will convert on assignment.
TIntermTyped* conversionTree = 0;
TVariable* tempRet = 0;
if (outputConversions) {
if (intermNode.getBasicType() != EbtVoid) {
// do the "tempRet = function(...), " bit from above
tempRet = makeInternalVariable("tempReturn", intermNode.getType());
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
} else
conversionTree = &intermNode;
if (intermNode.getBasicType() != EbtVoid) {
// do the "tempRet = function(...), " bit from above
tempRet = makeInternalVariable("tempReturn", intermNode.getType());
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());
conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc());
} else
conversionTree = &intermNode;
conversionTree = intermediate.makeAggregate(conversionTree);
}
conversionTree = intermediate.makeAggregate(conversionTree);
// Process each argument's conversion
for (int i = 0; i < function.getParamCount(); ++i) {
if (*function[i].type != arguments[i]->getAsTyped()->getType()) {
if (function[i].type->getQualifier().isParamInput()) {
// In-qualified arguments just need an extra node added above the argument to
// convert to the correct type.
arguments[i] = intermediate.addConversion(EOpAssign, *function[i].type, arguments[i]->getAsTyped());
} else if (function[i].type->getQualifier().isParamOutput()) {
if (function[i].type->getQualifier().isParamOutput()) {
// Out-qualified arguments need to use the topology set up above.
// do the " ...(tempArg, ...), arg = tempArg" bit from above
TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
@ -1108,11 +1149,7 @@ TIntermTyped* TParseContext::handleArgumentConversions(const TFunction& function
}
}
// Done if no output conversions
if (! outputConversions)
return &intermNode;
// Otherwise, finalize the tree topology (see bigger comment above).
// Finalize the tree topology (see bigger comment above).
if (tempRet) {
// do the "..., tempRet" bit from above
TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc());

View File

@ -98,7 +98,8 @@ public:
TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*);
TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*);
TIntermTyped* handleArgumentConversions(const TFunction&, TIntermAggregate&) const;
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&);
TFunction* handleConstructorCall(TSourceLoc, const TPublicType&);