From 7c983970e8713a417b444af55dad5484cfc1773d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 19 Mar 2011 14:51:57 -0700 Subject: [PATCH] Store the unique id from push_function() in the AST during semantic analysis. --- mojoshader.h | 1 + mojoshader_compiler.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/mojoshader.h b/mojoshader.h index c96e41ff..3913fd95 100644 --- a/mojoshader.h +++ b/mojoshader.h @@ -1539,6 +1539,7 @@ typedef struct MOJOSHADER_astCompilationUnitFunction 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 diff --git a/mojoshader_compiler.c b/mojoshader_compiler.c index 5da7e2f5..8e2c7d69 100644 --- a/mojoshader_compiler.c +++ b/mojoshader_compiler.c @@ -420,7 +420,7 @@ static inline void push_variable(Context *ctx, const char *sym, const MOJOSHADER 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,15 +429,6 @@ static void push_function(Context *ctx, const char *sym, assert(!ctx->is_func_scope); assert(dt->type == MOJOSHADER_AST_DATATYPE_FUNCTION); - int idx = 0; - if ((sym != NULL) && (dt != NULL)) - { - if (!dt->function.intrinsic) - idx = ++ctx->user_func_index; // these are positive. - else - 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. @@ -445,17 +436,31 @@ static void push_function(Context *ctx, const char *sym, 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. - if (datatypes_match(dt, ((SymbolScope *) value)->datatype)) + SymbolScope *item = (SymbolScope *) value; + if (datatypes_match(dt, item->datatype)) { if (!just_declare) failf(ctx, "Function '%s' already defined.", sym); - return; + return item->index; } // if } // while + int idx = 0; + if ((sym != NULL) && (dt != NULL)) + { + if (!dt->function.intrinsic) + idx = ++ctx->user_func_index; // these are positive. + else + idx = --ctx->intrinsic_func_index; // these are negative. + } // if + // 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 @@ static MOJOSHADER_astCompilationUnit *new_function(Context *ctx, retval->next = NULL; retval->declaration = declaration; retval->definition = definition; + retval->index = 0; return (MOJOSHADER_astCompilationUnit *) retval; } // new_function @@ -3082,8 +3088,9 @@ static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast) // 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 @@ static void intermediate_representation(Context *ctx) 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.