]> git.tdb.fi Git - libs/gl.git/commitdiff
Add support for function overloading
authorMikko Rasa <tdb@tdb.fi>
Tue, 9 Mar 2021 13:08:43 +0000 (15:08 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 9 Mar 2021 20:26:19 +0000 (22:26 +0200)
source/glsl/compiler.cpp
source/glsl/debug.cpp
source/glsl/generate.cpp
source/glsl/syntax.cpp
source/glsl/syntax.h
source/glsl/validate.cpp
source/glsl/visitor.cpp

index 332dd331f69b6bc6e287e89306e2e21eeff52e72..c5f0a9a3d05b6fd640f9afe5a5cba5a05e0ec5ab 100644 (file)
@@ -282,7 +282,7 @@ void Compiler::resolve(Stage &stage, unsigned flags)
                else if(resolve<FunctionResolver>(stage, flags, RESOLVE_FUNCTIONS))
                        flags |= RESOLVE_EXPRESSIONS;
                else if(resolve<ExpressionResolver>(stage, flags, RESOLVE_EXPRESSIONS))
                else if(resolve<FunctionResolver>(stage, flags, RESOLVE_FUNCTIONS))
                        flags |= RESOLVE_EXPRESSIONS;
                else if(resolve<ExpressionResolver>(stage, flags, RESOLVE_EXPRESSIONS))
-                       flags |= RESOLVE_VARIABLES;
+                       flags |= RESOLVE_VARIABLES|RESOLVE_FUNCTIONS;
        }
 }
 
        }
 }
 
index ef9e3e0eafc325a92f3bf389329c3efb3563b738..dd9db2f8ff760bdd92cd8e37fa24baa8141ee865 100644 (file)
@@ -393,7 +393,7 @@ void DumpTree::visit(InterfaceBlock &block)
 
 void DumpTree::visit(FunctionDeclaration &func)
 {
 
 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)
        if(func.source==BUILTIN_SOURCE)
                text += " (builtin)";
        else if(!func.definition)
@@ -401,6 +401,8 @@ void DumpTree::visit(FunctionDeclaration &func)
        append(text);
 
        begin_sub();
        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<VariableDeclaration>::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
                (*i)->visit(*this);
        last_branch();
        for(NodeArray<VariableDeclaration>::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
                (*i)->visit(*this);
        last_branch();
index 113b4324aa2b64432b41cf7be63ff13ca30ed8c4..29d52364c1506f1dc151aad780c584dc13b0eab6 100644 (file)
@@ -2,6 +2,7 @@
 #include <msp/core/hash.h>
 #include <msp/core/raii.h>
 #include <msp/strings/lexicalcast.h>
 #include <msp/core/hash.h>
 #include <msp/core/raii.h>
 #include <msp/strings/lexicalcast.h>
+#include <msp/strings/utils.h>
 #include "builtin.h"
 #include "generate.h"
 
 #include "builtin.h"
 #include "generate.h"
 
@@ -916,8 +917,22 @@ bool FunctionResolver::apply(Stage &s)
 
 void FunctionResolver::visit(FunctionCall &call)
 {
 
 void FunctionResolver::visit(FunctionCall &call)
 {
-       map<string, FunctionDeclaration *>::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<Expression>::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<string, FunctionDeclaration *>::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;
 
        r_any_resolved |= (declaration!=call.declaration);
        call.declaration = declaration;
 
@@ -926,8 +941,23 @@ void FunctionResolver::visit(FunctionCall &call)
 
 void FunctionResolver::visit(FunctionDeclaration &func)
 {
 
 void FunctionResolver::visit(FunctionDeclaration &func)
 {
-       FunctionDeclaration *&stage_decl = stage->functions[func.name];
-       vector<FunctionDeclaration *> &decls = declarations[func.name];
+       if(func.signature.empty())
+       {
+               string param_types;
+               for(NodeArray<VariableDeclaration>::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<FunctionDeclaration *> &decls = declarations[key];
        if(func.definition==&func)
        {
                stage_decl = &func;
        if(func.definition==&func)
        {
                stage_decl = &func;
index 71e5c39a948aabc7db12e701a80bcca32cfef3dc..cad7c9f4838962740c2036a6c91ab25517032e24 100644 (file)
@@ -404,6 +404,7 @@ FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
        name(other.name),
        parameters(other.parameters),
        body(other.body),
        name(other.name),
        parameters(other.parameters),
        body(other.body),
+       signature(other.signature),
        definition(other.definition==&other ? this : 0),
        return_type_declaration(0)
 { }
        definition(other.definition==&other ? this : 0),
        return_type_declaration(0)
 { }
index 3976af56aa77c97b2a8f430daa89514004209628..39bc8264e1b8d30ead80ad19ad78f9232a6cd3ae 100644 (file)
@@ -449,6 +449,7 @@ struct FunctionDeclaration: Statement
        NodeArray<VariableDeclaration> parameters;
        Block body;
 
        NodeArray<VariableDeclaration> parameters;
        Block body;
 
+       std::string signature;
        FunctionDeclaration *definition;
        TypeDeclaration *return_type_declaration;
 
        FunctionDeclaration *definition;
        TypeDeclaration *return_type_declaration;
 
index ea2e956d023f1e02d66b44b7771186542076dd28..f8ecc5eeefd34aaad243accf7034d9cee8513ca0 100644 (file)
@@ -175,15 +175,15 @@ void DeclarationValidator::visit(FunctionDeclaration &func)
 {
        if(Statement *previous = find_definition(func.name))
        {
 {
        if(Statement *previous = find_definition(func.name))
        {
-               FunctionDeclaration *prev_func = dynamic_cast<FunctionDeclaration *>(previous);
-               if(prev_func && prev_func->definition==&func)
-                       declarations[current_block][func.name] = &func;
-               else
+               if(!dynamic_cast<FunctionDeclaration *>(previous))
                        multiple_definition(format("'%s'", func.name), func, *previous);
        }
        else
                record_definition(func.name, func);
 
                        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);
 }
 
        TraversingVisitor::visit(func);
 }
 
index 8c8056c56352c99a56ca3a7e5b21e298026e5fbe..b1767d3f5748b2fcafb139e9de48098e92563a13 100644 (file)
@@ -200,7 +200,11 @@ void NodeRemover::visit(InterfaceBlock &iface)
 void NodeRemover::visit(FunctionDeclaration &func)
 {
        if(to_remove->count(&func))
 void NodeRemover::visit(FunctionDeclaration &func)
 {
        if(to_remove->count(&func))
+       {
                remove_from_map(stage->functions, func.name, 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);
 }
 
        TraversingVisitor::visit(func);
 }