HLSL: Non-functional: rationalize making constructors.
Improves foundation for adding scalar casts. Makes handle/make names more sane, better commented, uses more precise subclass typing, and removes mutual recursion between converting initializer lists and making constructors.
This commit is contained in:
parent
8df9a48698
commit
c633f644da
4 changed files with 30 additions and 14 deletions
|
|
@ -2,5 +2,5 @@
|
||||||
// For the version, it uses the latest git tag followed by the number of commits.
|
// For the version, it uses the latest git tag followed by the number of commits.
|
||||||
// For the date, it uses the current date (when then script is run).
|
// For the date, it uses the current date (when then script is run).
|
||||||
|
|
||||||
#define GLSLANG_REVISION "Overload400-PrecQual.1965"
|
#define GLSLANG_REVISION "Overload400-PrecQual.1971"
|
||||||
#define GLSLANG_DATE "03-Apr-2017"
|
#define GLSLANG_DATE "03-Apr-2017"
|
||||||
|
|
|
||||||
|
|
@ -2219,7 +2219,7 @@ bool HlslGrammar::acceptDefaultParameterDeclaration(const TType& type, TIntermTy
|
||||||
|
|
||||||
// For initializer lists, we have to const-fold into a constructor for the type, so build
|
// For initializer lists, we have to const-fold into a constructor for the type, so build
|
||||||
// that.
|
// that.
|
||||||
TFunction* constructor = parseContext.handleConstructorCall(token.loc, type);
|
TFunction* constructor = parseContext.makeConstructorCall(token.loc, type);
|
||||||
if (constructor == nullptr) // cannot construct
|
if (constructor == nullptr) // cannot construct
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -2628,7 +2628,7 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Hook it up like a constructor
|
// Hook it up like a constructor
|
||||||
TFunction* constructorFunction = parseContext.handleConstructorCall(loc, castType);
|
TFunction* constructorFunction = parseContext.makeConstructorCall(loc, castType);
|
||||||
if (constructorFunction == nullptr) {
|
if (constructorFunction == nullptr) {
|
||||||
expected("type that can be constructed");
|
expected("type that can be constructed");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2841,7 +2841,7 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
|
||||||
// type
|
// type
|
||||||
TType type;
|
TType type;
|
||||||
if (acceptType(type)) {
|
if (acceptType(type)) {
|
||||||
TFunction* constructorFunction = parseContext.handleConstructorCall(token.loc, type);
|
TFunction* constructorFunction = parseContext.makeConstructorCall(token.loc, type);
|
||||||
if (constructorFunction == nullptr)
|
if (constructorFunction == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3897,7 +3897,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
|
||||||
//
|
//
|
||||||
// It's a constructor, of type 'type'.
|
// It's a constructor, of type 'type'.
|
||||||
//
|
//
|
||||||
result = addConstructor(loc, arguments, type);
|
result = handleConstructor(loc, arguments, type);
|
||||||
if (result == nullptr)
|
if (result == nullptr)
|
||||||
error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
|
error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
@ -4308,9 +4308,13 @@ void HlslParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fn
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Handle seeing a built-in constructor in a grammar production.
|
// Handle seeing something in a grammar production that can be done by calling
|
||||||
|
// a constructor.
|
||||||
//
|
//
|
||||||
TFunction* HlslParseContext::handleConstructorCall(const TSourceLoc& loc, const TType& type)
|
// The constructor still must be "handled" by handleFunctionCall(), which will
|
||||||
|
// then call handleConstructor().
|
||||||
|
//
|
||||||
|
TFunction* HlslParseContext::makeConstructorCall(const TSourceLoc& loc, const TType& type)
|
||||||
{
|
{
|
||||||
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
|
|
@ -6495,9 +6499,9 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
|
||||||
|
|
||||||
// Now that the subtree is processed, process this node as if the
|
// Now that the subtree is processed, process this node as if the
|
||||||
// initializer list is a set of arguments to a constructor.
|
// initializer list is a set of arguments to a constructor.
|
||||||
TIntermNode* emulatedConstructorArguments;
|
TIntermTyped* emulatedConstructorArguments;
|
||||||
if (initList->getSequence().size() == 1)
|
if (initList->getSequence().size() == 1)
|
||||||
emulatedConstructorArguments = initList->getSequence()[0];
|
emulatedConstructorArguments = initList->getSequence()[0]->getAsTyped();
|
||||||
else
|
else
|
||||||
emulatedConstructorArguments = initList;
|
emulatedConstructorArguments = initList;
|
||||||
|
|
||||||
|
|
@ -6519,15 +6523,26 @@ void HlslParseContext::lengthenList(const TSourceLoc& loc, TIntermSequence& list
|
||||||
//
|
//
|
||||||
// Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
|
// Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
|
||||||
//
|
//
|
||||||
TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type)
|
TIntermTyped* HlslParseContext::handleConstructor(const TSourceLoc& loc, TIntermTyped* node, const TType& type)
|
||||||
{
|
{
|
||||||
if (node == nullptr || node->getAsTyped() == nullptr)
|
if (node == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Handle the idiom "(struct type)0"
|
// Handle the idiom "(struct type)0"
|
||||||
|
// Sequences (in an aggregate) for initialization are not yet tagged with
|
||||||
|
// an operator or type, so it is too early to ask if they are scalars.
|
||||||
if (type.isStruct() && isZeroConstructor(node))
|
if (type.isStruct() && isZeroConstructor(node))
|
||||||
return convertInitializerList(loc, type, intermediate.makeAggregate(loc));
|
return convertInitializerList(loc, type, intermediate.makeAggregate(loc));
|
||||||
|
|
||||||
|
return addConstructor(loc, node, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a constructor, either from the grammar, or other programmatic reasons.
|
||||||
|
//
|
||||||
|
// Return nullptr if it can't be done.
|
||||||
|
//
|
||||||
|
TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyped* node, const TType& type)
|
||||||
|
{
|
||||||
TIntermAggregate* aggrNode = node->getAsAggregate();
|
TIntermAggregate* aggrNode = node->getAsAggregate();
|
||||||
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
|
|
@ -6565,7 +6580,7 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermNod
|
||||||
else if (op == EOpConstructStruct)
|
else if (op == EOpConstructStruct)
|
||||||
newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
|
newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
|
||||||
else
|
else
|
||||||
newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false);
|
newNode = constructBuiltIn(type, op, node, node->getLoc(), false);
|
||||||
|
|
||||||
if (newNode && (type.isArray() || op == EOpConstructStruct))
|
if (newNode && (type.isArray() || op == EOpConstructStruct))
|
||||||
newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
|
newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc);
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ public:
|
||||||
void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
|
void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
|
||||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
|
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
|
||||||
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||||
TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
|
TFunction* makeConstructorCall(const TSourceLoc&, const TType&);
|
||||||
void handleSemantic(TSourceLoc, TQualifier&, TBuiltInVariable, const TString& upperCase);
|
void handleSemantic(TSourceLoc, TQualifier&, TBuiltInVariable, const TString& upperCase);
|
||||||
void handlePackOffset(const TSourceLoc&, TQualifier&, const glslang::TString& location,
|
void handlePackOffset(const TSourceLoc&, TQualifier&, const glslang::TString& location,
|
||||||
const glslang::TString* component);
|
const glslang::TString* component);
|
||||||
|
|
@ -141,7 +141,8 @@ public:
|
||||||
TSymbol* lookupUserType(const TString&, TType&);
|
TSymbol* lookupUserType(const TString&, TType&);
|
||||||
TIntermNode* declareVariable(const TSourceLoc&, const TString& identifier, TType&, TIntermTyped* initializer = 0);
|
TIntermNode* declareVariable(const TSourceLoc&, const TString& identifier, TType&, TIntermTyped* initializer = 0);
|
||||||
void lengthenList(const TSourceLoc&, TIntermSequence& list, int size);
|
void lengthenList(const TSourceLoc&, TIntermSequence& list, int size);
|
||||||
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
TIntermTyped* handleConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
|
||||||
|
TIntermTyped* addConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
|
||||||
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
||||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
||||||
void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue