Commit 6ed8d8af by Nicolas Capens

Produce constructors instead of conversions.

GLSL only supports explicit conversion through constructors. Therefore the conversion nodes are redundant. BUG=380353 Change-Id: Id871c34750191dac431bf72aac9afed7b0db7f8e Reviewed-on: https://chromium-review.googlesource.com/203452Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarNicolas Capens <nicolascapens@chromium.org>
parent 1af18dc9
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -188,23 +188,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
default: break;
}
//
// First try converting the children to compatible types.
//
if (left->getType().getStruct() && right->getType().getStruct()) {
if (left->getType() != right->getType())
return 0;
} else {
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child)
right = child;
else {
child = addConversion(op, right->getType(), left);
if (child)
left = child;
else
return 0;
}
if (left->getBasicType() != right->getBasicType())
{
return 0;
}
//
......@@ -241,19 +227,19 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
//
TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& line)
{
//
// Like adding binary math, except the conversion can only go
// from right to left.
//
if (left->getType().getStruct() || right->getType().getStruct())
{
if (left->getType() != right->getType())
{
return 0;
}
}
TIntermBinary* node = new TIntermBinary(op);
node->setLine(line);
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child == 0)
return 0;
node->setLeft(left);
node->setRight(child);
node->setRight(right);
if (! node->promote(infoSink))
return 0;
......@@ -311,42 +297,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
default: break;
}
//
// Do we need to promote the operand?
//
// Note: Implicit promotions were removed from the language.
//
TBasicType newType = EbtVoid;
switch (op) {
case EOpConstructInt: newType = EbtInt; break;
case EOpConstructUInt: newType = EbtUInt; break;
case EOpConstructBool: newType = EbtBool; break;
case EOpConstructFloat: newType = EbtFloat; break;
default: break;
}
if (newType != EbtVoid) {
child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary,
child->getNominalSize(),
child->getSecondarySize(),
child->isArray()),
child);
if (child == 0)
return 0;
}
//
// For constructors, we are now done, it's all in the conversion.
//
switch (op) {
case EOpConstructInt:
case EOpConstructUInt:
case EOpConstructBool:
case EOpConstructFloat:
return child;
default: break;
}
TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion())
childTempConstant = child->getAsConstantUnion();
......@@ -640,18 +590,9 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, c
//
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& line)
{
//
// Get compatible types.
//
TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
if (child)
falseBlock = child;
else {
child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
if (child)
trueBlock = child;
else
return 0;
if (trueBlock->getType() != falseBlock->getType())
{
return 0;
}
//
......@@ -1043,7 +984,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// GLSL ES 2.0 does not support implicit type casting.
// So the basic type should always match.
if (left->getBasicType() != right->getBasicType())
{
return false;
}
//
// Base assumption: just make the type the same as the left
......
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -1531,81 +1531,40 @@ TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
//
// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
//
TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc& line)
TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
{
if (node == 0)
return 0;
TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
if (!aggregateArguments)
{
aggregateArguments = new TIntermAggregate;
aggregateArguments->getSequence().push_back(arguments);
}
TIntermAggregate* aggrNode = node->getAsAggregate();
TFieldList::const_iterator memberTypes;
if (op == EOpConstructStruct)
memberTypes = type->getStruct()->fields().begin();
TType elementType = *type;
if (type->isArray())
elementType.clearArrayness();
bool singleArg;
if (aggrNode) {
if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
singleArg = true;
else
singleArg = false;
} else
singleArg = true;
TIntermTyped *newNode;
if (singleArg) {
// If structure constructor or array constructor is being called
// for only one parameter inside the structure, we need to call constructStruct function once.
if (type->isArray())
newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
else if (op == EOpConstructStruct)
newNode = constructStruct(node, (*memberTypes)->type(), 1, node->getLine(), false);
else
newNode = constructBuiltIn(type, op, node, node->getLine(), false);
{
const TFieldList &fields = type->getStruct()->fields();
TIntermSequence &args = aggregateArguments->getSequence();
if (newNode && newNode->getAsAggregate()) {
TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type);
if (constConstructor)
return constConstructor;
}
for (size_t i = 0; i < fields.size(); i++)
{
if (args[i]->getAsTyped()->getType() != *fields[i]->type())
{
error(line, "Structure constructor arguments do not match structure fields", "Error");
recover();
return newNode;
}
//
// Handle list of arguments.
//
TIntermSequence &sequenceVector = aggrNode->getSequence() ; // Stores the information about the parameter to the constructor
// if the structure constructor contains more than one parameter, then construct
// each parameter
int paramCount = 0; // keeps a track of the constructor parameter number being checked
// for each parameter to the constructor call, check to see if the right type is passed or convert them
// to the right type if possible (and allowed).
// for structure constructors, just check if the right type is passed, no conversion is allowed.
for (TIntermSequence::iterator p = sequenceVector.begin();
p != sequenceVector.end(); p++, paramCount++) {
if (type->isArray())
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
else if (op == EOpConstructStruct)
newNode = constructStruct(*p, (memberTypes[paramCount])->type(), paramCount+1, node->getLine(), true);
else
newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
if (newNode) {
*p = newNode;
return 0;
}
}
}
TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line);
TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
// Turn the argument list itself into a constructor
TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
if (constConstructor)
{
return constConstructor;
}
return constructor;
}
......
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