Move logic for resolving function call overloads.
This code previously lived in FunctionCallExpr but is now part of FunctionSymbolExpr. This change doesn't change any current functionality, but lays groundwork for function pointers in the language, where we'll want to do function call overload resolution at other times besides when a function call is actually being made.
This commit is contained in:
19
expr.h
19
expr.h
@@ -42,8 +42,6 @@
|
|||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
|
||||||
class FunctionSymbolExpr;
|
|
||||||
|
|
||||||
/** @brief Expr is the abstract base class that defines the interface that
|
/** @brief Expr is the abstract base class that defines the interface that
|
||||||
all expression types must implement.
|
all expression types must implement.
|
||||||
*/
|
*/
|
||||||
@@ -266,10 +264,6 @@ public:
|
|||||||
ExprList *args;
|
ExprList *args;
|
||||||
bool isLaunch;
|
bool isLaunch;
|
||||||
Expr *launchCountExpr;
|
Expr *launchCountExpr;
|
||||||
|
|
||||||
private:
|
|
||||||
void resolveFunctionOverloads(bool exactMatchOnly);
|
|
||||||
bool tryResolve(int (*matchFunc)(Expr *, const Type *));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -495,7 +489,8 @@ private:
|
|||||||
probably-different type. */
|
probably-different type. */
|
||||||
class TypeCastExpr : public Expr {
|
class TypeCastExpr : public Expr {
|
||||||
public:
|
public:
|
||||||
TypeCastExpr(const Type *t, Expr *e, SourcePos p);
|
TypeCastExpr(const Type *t, Expr *e, bool preserveUniformity,
|
||||||
|
SourcePos p);
|
||||||
|
|
||||||
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
|
||||||
const Type *GetType() const;
|
const Type *GetType() const;
|
||||||
@@ -506,6 +501,7 @@ public:
|
|||||||
|
|
||||||
const Type *type;
|
const Type *type;
|
||||||
Expr *expr;
|
Expr *expr;
|
||||||
|
bool preserveUniformity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -581,8 +577,12 @@ public:
|
|||||||
void Print() const;
|
void Print() const;
|
||||||
int EstimateCost() const;
|
int EstimateCost() const;
|
||||||
|
|
||||||
|
bool ResolveOverloads(const std::vector<Expr *> &args);
|
||||||
|
Symbol *GetMatchingFunction();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class FunctionCallExpr;
|
bool tryResolve(int (*matchFunc)(Expr *, const Type *),
|
||||||
|
const std::vector<Expr *> &args);
|
||||||
|
|
||||||
/** Name of the function that is being called. */
|
/** Name of the function that is being called. */
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -592,8 +592,7 @@ private:
|
|||||||
overload is the best match. */
|
overload is the best match. */
|
||||||
std::vector<Symbol *> *candidateFunctions;
|
std::vector<Symbol *> *candidateFunctions;
|
||||||
|
|
||||||
/** The actual matching function found after overload resolution; this
|
/** The actual matching function found after overload resolution. */
|
||||||
value is set by FunctionCallExpr::resolveFunctionOverloads() */
|
|
||||||
Symbol *matchingFunc;
|
Symbol *matchingFunc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
14
parse.yy
14
parse.yy
@@ -326,19 +326,13 @@ cast_expression
|
|||||||
: unary_expression
|
: unary_expression
|
||||||
| '(' type_name ')' cast_expression
|
| '(' type_name ')' cast_expression
|
||||||
{
|
{
|
||||||
// If type_name isn't explicitly a varying, We do a GetUniform()
|
// Pass true here to try to preserve uniformity
|
||||||
// call here so that things like:
|
// so that things like:
|
||||||
// uniform int y = ...;
|
// uniform int y = ...;
|
||||||
// uniform float x = 1. / (float)y;
|
// uniform float x = 1. / (float)y;
|
||||||
// don't issue an error due to (float)y being inadvertently
|
// don't issue an error due to (float)y being inadvertently
|
||||||
// and undesirably-to-the-user "varying"...
|
// and undesirably-to-the-user "varying"...
|
||||||
if ($2 == NULL || $4 == NULL || $4->GetType() == NULL)
|
$$ = new TypeCastExpr($2, $4, true, @1);
|
||||||
$$ = NULL;
|
|
||||||
else {
|
|
||||||
if ($4->GetType()->IsUniformType())
|
|
||||||
$2 = $2->GetAsUniformType();
|
|
||||||
$$ = new TypeCastExpr($2, $4, @1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -1463,7 +1457,7 @@ lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
|||||||
the actual enum type here and optimize it, which will have
|
the actual enum type here and optimize it, which will have
|
||||||
us end up with a ConstExpr with the desired EnumType... */
|
us end up with a ConstExpr with the desired EnumType... */
|
||||||
Expr *castExpr = new TypeCastExpr(enumType, enums[i]->constValue,
|
Expr *castExpr = new TypeCastExpr(enumType, enums[i]->constValue,
|
||||||
enums[i]->pos);
|
false, enums[i]->pos);
|
||||||
castExpr = castExpr->Optimize();
|
castExpr = castExpr->Optimize();
|
||||||
enums[i]->constValue = dynamic_cast<ConstExpr *>(castExpr);
|
enums[i]->constValue = dynamic_cast<ConstExpr *>(castExpr);
|
||||||
assert(enums[i]->constValue != NULL);
|
assert(enums[i]->constValue != NULL);
|
||||||
|
|||||||
19
stmt.cpp
19
stmt.cpp
@@ -519,15 +519,16 @@ Stmt *IfStmt::TypeCheck() {
|
|||||||
if (test) {
|
if (test) {
|
||||||
const Type *testType = test->GetType();
|
const Type *testType = test->GetType();
|
||||||
if (testType) {
|
if (testType) {
|
||||||
bool isUniform = testType->IsUniformType() && !g->opt.disableUniformControlFlow;
|
bool isUniform = (testType->IsUniformType() &&
|
||||||
|
!g->opt.disableUniformControlFlow);
|
||||||
if (!testType->IsNumericType() && !testType->IsBoolType()) {
|
if (!testType->IsNumericType() && !testType->IsBoolType()) {
|
||||||
Error(test->pos, "Type \"%s\" can't be converted to boolean for \"if\" test.",
|
Error(test->pos, "Type \"%s\" can't be converted to boolean "
|
||||||
testType->GetString().c_str());
|
"for \"if\" test.", testType->GetString().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
test = new TypeCastExpr(isUniform ? AtomicType::UniformBool :
|
test = new TypeCastExpr(isUniform ? AtomicType::UniformBool :
|
||||||
AtomicType::VaryingBool,
|
AtomicType::VaryingBool,
|
||||||
test, test->pos);
|
test, false, test->pos);
|
||||||
assert(test);
|
assert(test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1171,7 +1172,7 @@ DoStmt::TypeCheck() {
|
|||||||
!lHasVaryingBreakOrContinue(bodyStmts));
|
!lHasVaryingBreakOrContinue(bodyStmts));
|
||||||
testExpr = new TypeCastExpr(uniformTest ? AtomicType::UniformBool :
|
testExpr = new TypeCastExpr(uniformTest ? AtomicType::UniformBool :
|
||||||
AtomicType::VaryingBool,
|
AtomicType::VaryingBool,
|
||||||
testExpr, testExpr->pos);
|
testExpr, false, testExpr->pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1373,7 +1374,7 @@ ForStmt::TypeCheck() {
|
|||||||
!lHasVaryingBreakOrContinue(stmts));
|
!lHasVaryingBreakOrContinue(stmts));
|
||||||
test = new TypeCastExpr(uniformTest ? AtomicType::UniformBool :
|
test = new TypeCastExpr(uniformTest ? AtomicType::UniformBool :
|
||||||
AtomicType::VaryingBool,
|
AtomicType::VaryingBool,
|
||||||
test, test->pos);
|
test, false, test->pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1685,7 +1686,7 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
|
|||||||
baseType == AtomicType::UniformUInt16) {
|
baseType == AtomicType::UniformUInt16) {
|
||||||
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
|
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
|
||||||
AtomicType::VaryingInt32,
|
AtomicType::VaryingInt32,
|
||||||
expr, expr->pos);
|
expr, false, expr->pos);
|
||||||
type = expr->GetType();
|
type = expr->GetType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1908,7 +1909,7 @@ AssertStmt::TypeCheck() {
|
|||||||
}
|
}
|
||||||
expr = new TypeCastExpr(isUniform ? AtomicType::UniformBool :
|
expr = new TypeCastExpr(isUniform ? AtomicType::UniformBool :
|
||||||
AtomicType::VaryingBool,
|
AtomicType::VaryingBool,
|
||||||
expr, expr->pos);
|
expr, false, expr->pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
9
type.cpp
9
type.cpp
@@ -1887,6 +1887,15 @@ FunctionType::SetArgumentDefaults(const std::vector<ConstExpr *> &d) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
FunctionType::GetArgumentName(int i) const {
|
||||||
|
if (i >= (int)argNames.size())
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return argNames[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Type
|
// Type
|
||||||
|
|
||||||
|
|||||||
2
type.h
2
type.h
@@ -677,7 +677,7 @@ public:
|
|||||||
|
|
||||||
const std::vector<const Type *> &GetArgumentTypes() const { return argTypes; }
|
const std::vector<const Type *> &GetArgumentTypes() const { return argTypes; }
|
||||||
const std::vector<ConstExpr *> &GetArgumentDefaults() const { return argDefaults; }
|
const std::vector<ConstExpr *> &GetArgumentDefaults() const { return argDefaults; }
|
||||||
const std::string &GetArgumentName(int i) const { return argNames[i]; }
|
std::string GetArgumentName(int i) const;
|
||||||
|
|
||||||
/** @todo It would be nice to pull this information together and pass
|
/** @todo It would be nice to pull this information together and pass
|
||||||
it when the constructor is called; it's kind of ugly to set it like
|
it when the constructor is called; it's kind of ugly to set it like
|
||||||
|
|||||||
Reference in New Issue
Block a user