aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Capens <nicolascapens@chromium.org>2014-06-11 11:25:20 -0400
committerNicolas Capens <nicolascapens@chromium.org>2014-06-11 19:52:40 +0000
commit6ed8d8afdc5badae448e1851e8127ad616d37483 (patch)
treee447f6e1e9d6f60b69f4542a7bf549b5a84466f5
parent1af18dc97fe62bd5f9933179b7f79632261ed3d5 (diff)
downloadangle-6ed8d8afdc5badae448e1851e8127ad616d37483.tar.gz
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/203452 Reviewed-by: Shannon Woods <shannonwoods@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Tested-by: Nicolas Capens <nicolascapens@chromium.org>
-rw-r--r--src/compiler/translator/Intermediate.cpp93
-rw-r--r--src/compiler/translator/ParseContext.cpp91
2 files changed, 43 insertions, 141 deletions
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 9df2afc5..f4f35f34 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -1,5 +1,5 @@
//
-// 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
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index f9009668..52aced6b 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1,5 +1,5 @@
//
-// 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;
}