Index: src/sksl/SkSLIRGenerator.cpp |
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp |
index 07fd9e27b0ade573bae73994bcac6c91163a10d6..0c9ee2032865ec3e35a818ceb9e6facfde3ca60f 100644 |
--- a/src/sksl/SkSLIRGenerator.cpp |
+++ b/src/sksl/SkSLIRGenerator.cpp |
@@ -371,40 +371,11 @@ std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement |
return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); |
} |
-static const Type& expand_generics(const Type& type, int i) { |
- if (type.kind() == Type::kGeneric_Kind) { |
- return *type.coercibleTypes()[i]; |
- } |
- return type; |
-} |
- |
-static void expand_generics(const FunctionDeclaration& decl, |
- std::shared_ptr<SymbolTable> symbolTable) { |
- for (int i = 0; i < 4; i++) { |
- const Type& returnType = expand_generics(decl.fReturnType, i); |
- std::vector<const Variable*> parameters; |
- for (const auto& p : decl.fParameters) { |
- Variable* var = new Variable(p->fPosition, Modifiers(p->fModifiers), p->fName, |
- expand_generics(p->fType, i), |
- Variable::kParameter_Storage); |
- symbolTable->takeOwnership(var); |
- parameters.push_back(var); |
- } |
- symbolTable->add(decl.fName, std::unique_ptr<FunctionDeclaration>(new FunctionDeclaration( |
- decl.fPosition, |
- decl.fName, |
- std::move(parameters), |
- std::move(returnType)))); |
- } |
-} |
- |
std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFunction& f) { |
- bool isGeneric; |
const Type* returnType = this->convertType(*f.fReturnType); |
if (!returnType) { |
return nullptr; |
} |
- isGeneric = returnType->kind() == Type::kGeneric_Kind; |
std::vector<const Variable*> parameters; |
for (const auto& param : f.fParameters) { |
const Type* type = this->convertType(*param->fType); |
@@ -425,7 +396,6 @@ std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti |
Variable::kParameter_Storage); |
fSymbolTable->takeOwnership(var); |
parameters.push_back(var); |
- isGeneric |= type->kind() == Type::kGeneric_Kind; |
} |
// find existing declaration |
@@ -483,19 +453,12 @@ std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti |
} |
if (!decl) { |
// couldn't find an existing declaration |
- if (isGeneric) { |
- ASSERT(!f.fBody); |
- expand_generics(FunctionDeclaration(f.fPosition, f.fName, parameters, *returnType), |
- fSymbolTable); |
- } else { |
- auto newDecl = std::unique_ptr<FunctionDeclaration>(new FunctionDeclaration( |
- f.fPosition, |
- f.fName, |
- parameters, |
- *returnType)); |
- decl = newDecl.get(); |
- fSymbolTable->add(decl->fName, std::move(newDecl)); |
- } |
+ auto newDecl = std::unique_ptr<FunctionDeclaration>(new FunctionDeclaration(f.fPosition, |
+ f.fName, |
+ parameters, |
+ *returnType)); |
+ decl = newDecl.get(); |
+ fSymbolTable->add(decl->fName, std::move(newDecl)); |
} |
if (f.fBody) { |
ASSERT(!fCurrentFunction); |
@@ -915,8 +878,22 @@ std::unique_ptr<Expression> IRGenerator::call(Position position, |
fErrors.error(position, msg); |
return nullptr; |
} |
+ std::vector<const Type*> types; |
+ const Type* returnType; |
+ if (!function.determineFinalTypes(arguments, &types, &returnType)) { |
+ std::string msg = "no match for " + function.fName + "("; |
+ std::string separator = ""; |
+ for (size_t i = 0; i < arguments.size(); i++) { |
+ msg += separator; |
+ separator = ", "; |
+ msg += arguments[i]->fType.description(); |
+ } |
+ msg += ")"; |
+ fErrors.error(position, msg); |
+ return nullptr; |
+ } |
for (size_t i = 0; i < arguments.size(); i++) { |
- arguments[i] = this->coerce(std::move(arguments[i]), function.fParameters[i]->fType); |
+ arguments[i] = this->coerce(std::move(arguments[i]), *types[i]); |
if (!arguments[i]) { |
return nullptr; |
} |
@@ -924,7 +901,7 @@ std::unique_ptr<Expression> IRGenerator::call(Position position, |
this->markWrittenTo(*arguments[i]); |
} |
} |
- return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, |
+ return std::unique_ptr<FunctionCall>(new FunctionCall(position, *returnType, function, |
std::move(arguments))); |
} |
@@ -940,9 +917,14 @@ bool IRGenerator::determineCallCost(const FunctionDeclaration& function, |
return false; |
} |
int total = 0; |
+ std::vector<const Type*> types; |
+ const Type* ignored; |
+ if (!function.determineFinalTypes(arguments, &types, &ignored)) { |
+ return false; |
+ } |
for (size_t i = 0; i < arguments.size(); i++) { |
int cost; |
- if (arguments[i]->fType.determineCoercionCost(function.fParameters[i]->fType, &cost)) { |
+ if (arguments[i]->fType.determineCoercionCost(*types[i], &cost)) { |
total += cost; |
} else { |
return false; |