From: Mikko Rasa Date: Tue, 9 Mar 2021 13:08:43 +0000 (+0200) Subject: Add support for function overloading X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=a1ba04add302e7712d127b46d8d11386987a0aea Add support for function overloading --- diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 332dd331..c5f0a9a3 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -282,7 +282,7 @@ void Compiler::resolve(Stage &stage, unsigned flags) else if(resolve(stage, flags, RESOLVE_FUNCTIONS)) flags |= RESOLVE_EXPRESSIONS; else if(resolve(stage, flags, RESOLVE_EXPRESSIONS)) - flags |= RESOLVE_VARIABLES; + flags |= RESOLVE_VARIABLES|RESOLVE_FUNCTIONS; } } diff --git a/source/glsl/debug.cpp b/source/glsl/debug.cpp index ef9e3e0e..dd9db2f8 100644 --- a/source/glsl/debug.cpp +++ b/source/glsl/debug.cpp @@ -393,7 +393,7 @@ void DumpTree::visit(InterfaceBlock &block) void DumpTree::visit(FunctionDeclaration &func) { - string text = format("%%%d %s %s", get_label(func), func.return_type, func.name); + string text = format("%%%d %s %s%s", get_label(func), func.return_type, func.name, (func.signature.empty() ? "(?)" : func.signature)); if(func.source==BUILTIN_SOURCE) text += " (builtin)"; else if(!func.definition) @@ -401,6 +401,8 @@ void DumpTree::visit(FunctionDeclaration &func) append(text); begin_sub(); + if(func.return_type_declaration) + append(format("Return type: %%%d %s", get_label(*func.return_type_declaration), func.return_type_declaration->name)); for(NodeArray::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) (*i)->visit(*this); last_branch(); diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 113b4324..29d52364 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "builtin.h" #include "generate.h" @@ -916,8 +917,22 @@ bool FunctionResolver::apply(Stage &s) void FunctionResolver::visit(FunctionCall &call) { - map::iterator i = stage->functions.find(call.name); - FunctionDeclaration *declaration = (i!=stage->functions.end() ? i->second : 0); + string arg_types; + bool has_signature = true; + for(NodeArray::const_iterator i=call.arguments.begin(); (has_signature && i!=call.arguments.end()); ++i) + { + if((*i)->type) + append(arg_types, ",", (*i)->type->name); + else + has_signature = false; + } + + FunctionDeclaration *declaration = 0; + if(has_signature) + { + map::iterator i = stage->functions.find(format("%s(%s)", call.name, arg_types)); + declaration = (i!=stage->functions.end() ? i->second : 0); + } r_any_resolved |= (declaration!=call.declaration); call.declaration = declaration; @@ -926,8 +941,23 @@ void FunctionResolver::visit(FunctionCall &call) void FunctionResolver::visit(FunctionDeclaration &func) { - FunctionDeclaration *&stage_decl = stage->functions[func.name]; - vector &decls = declarations[func.name]; + if(func.signature.empty()) + { + string param_types; + for(NodeArray::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) + { + if((*i)->type_declaration) + append(param_types, ",", (*i)->type_declaration->name); + else + return; + } + func.signature = format("(%s)", param_types); + r_any_resolved = true; + } + + string key = func.name+func.signature; + FunctionDeclaration *&stage_decl = stage->functions[key]; + vector &decls = declarations[key]; if(func.definition==&func) { stage_decl = &func; diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index 71e5c39a..cad7c9f4 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -404,6 +404,7 @@ FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other): name(other.name), parameters(other.parameters), body(other.body), + signature(other.signature), definition(other.definition==&other ? this : 0), return_type_declaration(0) { } diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index 3976af56..39bc8264 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -449,6 +449,7 @@ struct FunctionDeclaration: Statement NodeArray parameters; Block body; + std::string signature; FunctionDeclaration *definition; TypeDeclaration *return_type_declaration; diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index ea2e956d..f8ecc5ee 100644 --- a/source/glsl/validate.cpp +++ b/source/glsl/validate.cpp @@ -175,15 +175,15 @@ void DeclarationValidator::visit(FunctionDeclaration &func) { if(Statement *previous = find_definition(func.name)) { - FunctionDeclaration *prev_func = dynamic_cast(previous); - if(prev_func && prev_func->definition==&func) - declarations[current_block][func.name] = &func; - else + if(!dynamic_cast(previous)) multiple_definition(format("'%s'", func.name), func, *previous); } else record_definition(func.name, func); + if(func.definition==&func) + check_definition(func.name+func.signature, func); + TraversingVisitor::visit(func); } diff --git a/source/glsl/visitor.cpp b/source/glsl/visitor.cpp index 8c8056c5..b1767d3f 100644 --- a/source/glsl/visitor.cpp +++ b/source/glsl/visitor.cpp @@ -200,7 +200,11 @@ void NodeRemover::visit(InterfaceBlock &iface) void NodeRemover::visit(FunctionDeclaration &func) { if(to_remove->count(&func)) + { remove_from_map(stage->functions, func.name, func); + if(!func.signature.empty()) + remove_from_map(stage->functions, func.name+func.signature, func); + } TraversingVisitor::visit(func); }