diff options
author | Nicolas Capens <nicolascapens@chromium.org> | 2014-06-11 11:25:20 -0400 |
---|---|---|
committer | Nicolas Capens <nicolascapens@chromium.org> | 2014-06-11 19:52:40 +0000 |
commit | 6ed8d8afdc5badae448e1851e8127ad616d37483 (patch) | |
tree | e447f6e1e9d6f60b69f4542a7bf549b5a84466f5 | |
parent | 1af18dc97fe62bd5f9933179b7f79632261ed3d5 (diff) | |
download | angle-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.cpp | 93 | ||||
-rw-r--r-- | src/compiler/translator/ParseContext.cpp | 91 |
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; } |