Merge pull request #647 from steve-lunarg/default-fn-params
HLSL: default function parameters
This commit is contained in:
commit
c4ed950057
15 changed files with 1263 additions and 24 deletions
|
|
@ -629,6 +629,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||
//
|
||||
TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||
{
|
||||
if (aggrNode == nullptr)
|
||||
return aggrNode;
|
||||
|
||||
if (! areAllChildConst(aggrNode))
|
||||
return aggrNode;
|
||||
|
||||
|
|
|
|||
|
|
@ -348,13 +348,18 @@ const TFunction* TParseContextBase::selectFunction(
|
|||
for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
|
||||
const TFunction& candidate = *(*it);
|
||||
|
||||
// to even be a potential match, number of arguments has to match
|
||||
if (call.getParamCount() != candidate.getParamCount())
|
||||
// to even be a potential match, number of arguments must be >= the number of
|
||||
// fixed (non-default) parameters, and <= the total (including parameter with defaults).
|
||||
if (call.getParamCount() < candidate.getFixedParamCount() ||
|
||||
call.getParamCount() > candidate.getParamCount())
|
||||
continue;
|
||||
|
||||
// see if arguments are convertible
|
||||
bool viable = true;
|
||||
for (int param = 0; param < candidate.getParamCount(); ++param) {
|
||||
|
||||
// The call can have fewer parameters than the candidate, if some have defaults.
|
||||
const int paramCount = std::min(call.getParamCount(), candidate.getParamCount());
|
||||
for (int param = 0; param < paramCount; ++param) {
|
||||
if (candidate[param].type->getQualifier().isParamInput()) {
|
||||
if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) {
|
||||
viable = false;
|
||||
|
|
@ -382,7 +387,7 @@ const TFunction* TParseContextBase::selectFunction(
|
|||
return viableCandidates.front();
|
||||
|
||||
// 4. find best...
|
||||
auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
|
||||
const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
|
||||
// is call -> can2 better than call -> can1 for any parameter
|
||||
bool hasBetterParam = false;
|
||||
for (int param = 0; param < call.getParamCount(); ++param) {
|
||||
|
|
@ -394,6 +399,16 @@ const TFunction* TParseContextBase::selectFunction(
|
|||
return hasBetterParam;
|
||||
};
|
||||
|
||||
const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
|
||||
// is call -> can2 equivalent to call -> can1 for all the call parameters?
|
||||
for (int param = 0; param < call.getParamCount(); ++param) {
|
||||
if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
|
||||
better(*call[param].type, *can2[param].type, *can1[param].type))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const TFunction* incumbent = viableCandidates.front();
|
||||
for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
|
||||
const TFunction& candidate = *(*it);
|
||||
|
|
@ -406,7 +421,10 @@ const TFunction* TParseContextBase::selectFunction(
|
|||
if (incumbent == *it)
|
||||
continue;
|
||||
const TFunction& candidate = *(*it);
|
||||
if (betterParam(*incumbent, candidate))
|
||||
|
||||
// In the case of default parameters, it may have an identical initial set, which is
|
||||
// also ambiguous
|
||||
if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
|
||||
tie = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
|
|||
op = copyOf.op;
|
||||
defined = copyOf.defined;
|
||||
prototyped = copyOf.prototyped;
|
||||
defaultParamCount = copyOf.defaultParamCount;
|
||||
}
|
||||
|
||||
TFunction* TFunction::clone() const
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ protected:
|
|||
struct TParameter {
|
||||
TString *name;
|
||||
TType* type;
|
||||
TIntermTyped* defaultValue;
|
||||
void copyParam(const TParameter& param)
|
||||
{
|
||||
if (param.name)
|
||||
|
|
@ -198,6 +199,7 @@ struct TParameter {
|
|||
else
|
||||
name = 0;
|
||||
type = param.type->clone();
|
||||
defaultValue = param.defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -209,12 +211,12 @@ public:
|
|||
explicit TFunction(TOperator o) :
|
||||
TSymbol(0),
|
||||
op(o),
|
||||
defined(false), prototyped(false) { }
|
||||
defined(false), prototyped(false), defaultParamCount(0) { }
|
||||
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
||||
TSymbol(name),
|
||||
mangledName(*name + '('),
|
||||
op(tOp),
|
||||
defined(false), prototyped(false) { returnType.shallowCopy(retType); }
|
||||
defined(false), prototyped(false), defaultParamCount(0) { returnType.shallowCopy(retType); }
|
||||
virtual TFunction* clone() const;
|
||||
virtual ~TFunction();
|
||||
|
||||
|
|
@ -226,6 +228,9 @@ public:
|
|||
assert(writable);
|
||||
parameters.push_back(p);
|
||||
p.type->appendMangledName(mangledName);
|
||||
|
||||
if (p.defaultValue != nullptr)
|
||||
defaultParamCount++;
|
||||
}
|
||||
|
||||
virtual const TString& getMangledName() const { return mangledName; }
|
||||
|
|
@ -238,7 +243,13 @@ public:
|
|||
virtual void setPrototyped() { assert(writable); prototyped = true; }
|
||||
virtual bool isPrototyped() const { return prototyped; }
|
||||
|
||||
// Return total number of parameters
|
||||
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
|
||||
// Return number of parameters with default values.
|
||||
virtual int getDefaultParamCount() const { return defaultParamCount; }
|
||||
// Return number of fixed parameters (without default values)
|
||||
virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }
|
||||
|
||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||
|
||||
|
|
@ -255,6 +266,7 @@ protected:
|
|||
TOperator op;
|
||||
bool defined;
|
||||
bool prototyped;
|
||||
int defaultParamCount;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue