Skip to content

Commit

Permalink
Clean up bogus usertypes leftover from parse phase, during semantic a…
Browse files Browse the repository at this point in the history
…nalysis.
  • Loading branch information
icculus committed Jan 13, 2011
1 parent 81bf097 commit 372e723
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
61 changes: 44 additions & 17 deletions mojoshader_compiler.c
Expand Up @@ -104,6 +104,7 @@ typedef struct Context
int intrinsic_func_index; // next function index for intrinsic functions.

// Cache intrinsic types for fast lookup and consistent pointer values.
MOJOSHADER_astDataType dt_none;
MOJOSHADER_astDataType dt_bool;
MOJOSHADER_astDataType dt_int;
MOJOSHADER_astDataType dt_uint;
Expand Down Expand Up @@ -1804,15 +1805,37 @@ static int calc_ast_const_expr(Context *ctx, void *_expr, AstCalcData *data)
} // calc_ast_const_expr


static inline const MOJOSHADER_astDataType *reduce_datatype(const MOJOSHADER_astDataType *dt)
static const MOJOSHADER_astDataType *reduce_datatype(Context *ctx, const MOJOSHADER_astDataType *dt)
{
const MOJOSHADER_astDataType *retval = dt;
while (retval && retval->type == MOJOSHADER_AST_DATATYPE_USER)
retval = retval->user.details;
{
// !!! FIXME: Ugh, const removal.
MOJOSHADER_astDataTypeUser *user = (MOJOSHADER_astDataTypeUser *) &retval->user;
if (user->details->type == MOJOSHADER_AST_DATATYPE_NONE)
{
// Take this opportunity to fix up some usertype stubs that were
// left over from the parse phase. You HAVE to catch these in the
// right scope, so be aggressive about calling reduce_datatype()
// as soon as things come into view!
user->details = get_usertype(ctx, user->name);
assert(user->details != NULL);
} // if

retval = user->details;
} // while

return retval;
} // reduce_datatype


static inline const MOJOSHADER_astDataType *sanitize_datatype(Context *ctx, const MOJOSHADER_astDataType *dt)
{
reduce_datatype(ctx, dt);
return dt;
} // sanitize_datatype


static const MOJOSHADER_astDataType *build_function_datatype(Context *ctx,
const MOJOSHADER_astDataType *rettype,
const int paramcount,
Expand Down Expand Up @@ -1864,6 +1887,8 @@ static const MOJOSHADER_astDataType *build_datatype(Context *ctx,
assert( (soa->isarray && soa->dimension) ||
(!soa->isarray && !soa->dimension) );

sanitize_datatype(ctx, dt);

// see if we can just reuse the exist datatype.
if (!soa->isarray)
{
Expand Down Expand Up @@ -1930,7 +1955,7 @@ static const MOJOSHADER_astDataType *build_datatype(Context *ctx,
static void require_numeric_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
switch (datatype->type)
{
case MOJOSHADER_AST_DATATYPE_BOOL:
Expand All @@ -1950,7 +1975,7 @@ static void require_numeric_datatype(Context *ctx,
static void require_integer_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
switch (datatype->type)
{
case MOJOSHADER_AST_DATATYPE_INT:
Expand All @@ -1966,7 +1991,7 @@ static void require_integer_datatype(Context *ctx,
static void require_boolean_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
switch (datatype->type)
{
case MOJOSHADER_AST_DATATYPE_BOOL:
Expand All @@ -1984,7 +2009,7 @@ static void require_boolean_datatype(Context *ctx,
static void require_array_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
if (datatype->type == MOJOSHADER_AST_DATATYPE_ARRAY)
return;

Expand All @@ -1996,7 +2021,7 @@ static void require_array_datatype(Context *ctx,
static void require_struct_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
if (datatype->type == MOJOSHADER_AST_DATATYPE_STRUCT)
return;

Expand All @@ -2008,7 +2033,7 @@ static void require_struct_datatype(Context *ctx,
static int require_function_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
if ((!datatype) || (datatype->type != MOJOSHADER_AST_DATATYPE_FUNCTION))
{
fail(ctx, "expected function");
Expand All @@ -2023,7 +2048,7 @@ static int require_function_datatype(Context *ctx,
static const MOJOSHADER_astDataType *array_element_datatype(Context *ctx,
const MOJOSHADER_astDataType *datatype)
{
datatype = reduce_datatype(datatype);
datatype = reduce_datatype(ctx, datatype);
assert(datatype->type == MOJOSHADER_AST_DATATYPE_ARRAY);
return datatype->array.base;
} // array_element_datatype
Expand All @@ -2043,8 +2068,8 @@ static const MOJOSHADER_astDataType *add_type_coercion(Context *ctx,
const MOJOSHADER_astDataType *_rdatatype)
{
// !!! FIXME: this whole function is probably naive at best.
const MOJOSHADER_astDataType *ldatatype = reduce_datatype(_ldatatype);
const MOJOSHADER_astDataType *rdatatype = reduce_datatype(_rdatatype);
const MOJOSHADER_astDataType *ldatatype = reduce_datatype(ctx, _ldatatype);
const MOJOSHADER_astDataType *rdatatype = reduce_datatype(ctx, _rdatatype);

if (ldatatype == rdatatype)
return ldatatype; // they already match, so we're done.
Expand Down Expand Up @@ -2173,7 +2198,7 @@ static const MOJOSHADER_astDataType *match_func_to_call(Context *ctx,
{
SymbolScope *item = (SymbolScope *) value;
const MOJOSHADER_astDataType *dt = item->datatype;
dt = reduce_datatype(dt);
dt = reduce_datatype(ctx, dt);
// there's a locally-scoped symbol with this name? It takes precedence.
if (dt->type != MOJOSHADER_AST_DATATYPE_FUNCTION)
return dt;
Expand Down Expand Up @@ -2219,7 +2244,7 @@ static const MOJOSHADER_astDataType *match_func_to_call(Context *ctx,
failf(ctx, "No matching function named '%s'", sym);
else
{
ident->datatype = reduce_datatype(best->datatype);
ident->datatype = reduce_datatype(ctx, best->datatype);
ident->index = best->index;
} // else

Expand Down Expand Up @@ -2280,7 +2305,7 @@ static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast)
{
const char *member = ast->derefstruct.member;
datatype = type_check_ast(ctx, ast->derefstruct.identifier);
const MOJOSHADER_astDataType *reduced = reduce_datatype(datatype);
const MOJOSHADER_astDataType *reduced = reduce_datatype(ctx, datatype);

// Is this a swizzle and not a struct deref?
if (reduced->type == MOJOSHADER_AST_DATATYPE_VECTOR)
Expand Down Expand Up @@ -2437,7 +2462,7 @@ static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast)
case MOJOSHADER_AST_OP_CALLFUNC:
{
datatype = match_func_to_call(ctx, &ast->callfunc);
const MOJOSHADER_astDataType *reduced = reduce_datatype(datatype);
const MOJOSHADER_astDataType *reduced = reduce_datatype(ctx, datatype);
// !!! FIXME: replace AST node with an int if this isn't a func.
if (!require_function_datatype(ctx, reduced))
{
Expand Down Expand Up @@ -2471,7 +2496,7 @@ static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast)

case MOJOSHADER_AST_OP_CONSTRUCTOR:
{
const MOJOSHADER_astDataType *reduced = reduce_datatype(ast->constructor.datatype);
const MOJOSHADER_astDataType *reduced = reduce_datatype(ctx, ast->constructor.datatype);
const MOJOSHADER_astDataType *base_dt = reduced;
int num_params = 1;

Expand Down Expand Up @@ -2546,7 +2571,7 @@ static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast)
} // case

case MOJOSHADER_AST_OP_CAST:
datatype = ast->cast.datatype;
datatype = sanitize_datatype(ctx, ast->cast.datatype);
datatype2 = type_check_ast(ctx, ast->cast.operand);
// you still need type coercion, since you could do a wrong cast,
// like "int x = (short) mychar;"
Expand Down Expand Up @@ -2729,6 +2754,7 @@ static const MOJOSHADER_astDataType *type_check_ast(Context *ctx, void *_ast)
for (param = ast->funcsig.params; param; param = param->next)
{
assert(i <= STATICARRAYLEN(dtparams)); // laziness.
sanitize_datatype(ctx, param->datatype);
if (param->initializer != NULL)
{
datatype2 = type_check_ast(ctx, param->initializer);
Expand Down Expand Up @@ -3161,6 +3187,7 @@ static Context *build_context(MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
// !!! FIXME: this feels hacky.
ctx->garbage = buffer_create(256*sizeof(void*),MallocBridge,FreeBridge,ctx); // !!! FIXME: check for failure.

ctx->dt_none.type = MOJOSHADER_AST_DATATYPE_NONE;
ctx->dt_bool.type = MOJOSHADER_AST_DATATYPE_BOOL;
ctx->dt_int.type = MOJOSHADER_AST_DATATYPE_INT;
ctx->dt_uint.type = MOJOSHADER_AST_DATATYPE_UINT;
Expand Down
2 changes: 1 addition & 1 deletion mojoshader_parser_hlsl.lemon
Expand Up @@ -226,7 +226,7 @@ struct_declaration(A) ::= struct_intro(B) LBRACE struct_member_list(C) RBRACE. {

// This has to be separate from struct_declaration so that the struct is in the usertypemap when parsing its members.
%type struct_intro { const char * }
struct_intro(A) ::= STRUCT IDENTIFIER(B). { A = B.string; push_usertype(ctx, A, &ctx->dt_int); } // datatype is bogus until semantic analysis.
struct_intro(A) ::= STRUCT IDENTIFIER(B). { A = B.string; push_usertype(ctx, A, &ctx->dt_none); } // datatype is bogus until semantic analysis.

%type struct_member_list { MOJOSHADER_astStructMembers * }
%destructor struct_member_list { delete_struct_member(ctx, $$); }
Expand Down

0 comments on commit 372e723

Please sign in to comment.