Store the unique id from push_function() in the AST during semantic analysis.
authorRyan C. Gordon <icculus@icculus.org>
Sat, 19 Mar 2011 14:51:57 -0700
changeset 1014 7db1c2dfead6
parent 1013 b41b88d368b0
child 1015 87c39e720f36
Store the unique id from push_function() in the AST during semantic analysis.
mojoshader.h
mojoshader_compiler.c
--- a/mojoshader.h	Sat Mar 19 04:32:29 2011 -0400
+++ b/mojoshader.h	Sat Mar 19 14:51:57 2011 -0700
@@ -1539,6 +1539,7 @@
     MOJOSHADER_astCompilationUnit *next;
     MOJOSHADER_astFunctionSignature *declaration;
     MOJOSHADER_astStatement *definition;
+    int index;  /* unique id. Will be 0 until semantic analysis runs. */
 } MOJOSHADER_astCompilationUnitFunction;
 
 typedef struct MOJOSHADER_astCompilationUnitTypedef
--- a/mojoshader_compiler.c	Sat Mar 19 04:32:29 2011 -0400
+++ b/mojoshader_compiler.c	Sat Mar 19 14:51:57 2011 -0700
@@ -420,7 +420,7 @@
     push_symbol(ctx, &ctx->variables, sym, dt, idx, 1);
 } // push_variable
 
-static void push_function(Context *ctx, const char *sym,
+static int push_function(Context *ctx, const char *sym,
                           const MOJOSHADER_astDataType *dt,
                           const int just_declare)
 {
@@ -429,6 +429,25 @@
     assert(!ctx->is_func_scope);
     assert(dt->type == MOJOSHADER_AST_DATATYPE_FUNCTION);
 
+    // Functions are always global, so no need to search scopes.
+    //  Functions overload, though, so we have to continue iterating to
+    //  see if it matches anything.
+    const void *value = NULL;
+    void *iter = NULL;
+    while (hash_iter(ctx->variables.hash, sym, &value, &iter))
+    {
+        // !!! FIXME: this breaks if you predeclare a function.
+        // !!! FIXME:  (a declare AFTER defining works, though.)
+        // there's already something called this.
+        SymbolScope *item = (SymbolScope *) value;
+        if (datatypes_match(dt, item->datatype))
+        {
+            if (!just_declare)
+                failf(ctx, "Function '%s' already defined.", sym);
+            return item->index;
+        } // if
+    } // while
+
     int idx = 0;
     if ((sym != NULL) && (dt != NULL))
     {
@@ -438,24 +457,10 @@
             idx = --ctx->intrinsic_func_index;  // these are negative.
     } // if
 
-    // Functions are always global, so no need to search scopes.
-    //  Functions overload, though, so we have to continue iterating to
-    //  see if it matches anything.
-    const void *value = NULL;
-    void *iter = NULL;
-    while (hash_iter(ctx->variables.hash, sym, &value, &iter))
-    {
-        // there's already something called this.
-        if (datatypes_match(dt, ((SymbolScope *) value)->datatype))
-        {
-            if (!just_declare)
-                failf(ctx, "Function '%s' already defined.", sym);
-            return;
-        } // if
-    } // while
-
     // push_symbol() doesn't check dupes, because we just did.
     push_symbol(ctx, &ctx->variables, sym, dt, idx, 0);
+
+    return idx;
 } // push_function
 
 static inline void push_scope(Context *ctx)
@@ -865,6 +870,7 @@
     retval->next = NULL;
     retval->declaration = declaration;
     retval->definition = definition;
+    retval->index = 0;
     return (MOJOSHADER_astCompilationUnit *) retval;
 } // new_function
 
@@ -3082,8 +3088,9 @@
             //  the global scope, but it's parameters are pushed as variables
             //  in the function's scope.
             datatype = type_check_ast(ctx, ast->funcunit.declaration);
-            push_function(ctx, ast->funcunit.declaration->identifier,
-                          datatype, ast->funcunit.definition == NULL);
+            ast->funcunit.index = push_function(ctx,
+                                ast->funcunit.declaration->identifier,
+                                datatype, ast->funcunit.definition == NULL);
 
             // not just a declaration, but a full function definition?
             if (ast->funcunit.definition != NULL)
@@ -5919,7 +5926,7 @@
         ctx->ir_end = -1;
         ctx->ir_ret = -1;
 
-printf("[FUNCTION %s ]\n", astfn->declaration->identifier); print_ir(stdout, 1, funcseq);
+printf("[FUNCTION %d ]\n", astfn->index); print_ir(stdout, 1, funcseq);
     } // for
 
     // done with the AST, nuke it.