HLSL: allow self-type cast (as no-op passthrough)

Previously, casting an object of a struct type to an identical type
would produce an error.  This PR allows this case.

As a side-effect of the change, several self-type casts in existing
tests go away.  For example:

    0:10          Construct float ( temp float)
    0:10            'f' ( in float)

becomes this (without the unneeded constructor op):

    0:10          'f' ( in float)

For vector or array types this can result in somewhat less overall code.

Fixes: #1218
This commit is contained in:
LoopDawg 2018-05-17 13:03:12 -06:00
parent ebec909487
commit c59916710e
6 changed files with 205 additions and 48 deletions

View file

@ -6401,12 +6401,18 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
return true;
}
if (op == EOpConstructStruct && ! type.isArray() && isScalarConstructor(node))
return false;
if (op == EOpConstructStruct && ! type.isArray()) {
if (isScalarConstructor(node))
return false;
if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
return true;
// Self-type construction: e.g, we can construct a struct from a single identically typed object.
if (function.getParamCount() == 1 && type == *function[0].type)
return false;
if ((int)type.getStruct()->size() != function.getParamCount()) {
error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
return true;
}
}
if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) ||
@ -8132,6 +8138,10 @@ TIntermTyped* HlslParseContext::handleConstructor(const TSourceLoc& loc, TInterm
if (node == nullptr)
return nullptr;
// Construct identical type
if (type == node->getType())
return node;
// Handle the idiom "(struct type)<scalar value>"
if (type.isStruct() && isScalarConstructor(node)) {
// 'node' will almost always get used multiple times, so should not be used directly,