From 0b5565396b928bc877b3eb8ac57b74e2b273b53b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 13 Feb 2011 16:05:09 +0900 Subject: [PATCH] Add a class type to symbols and rework the CLASS_NAME handling. This fixes the problem with [Array alloc] producing a warning about Class not repsonding to -alloc. --- tools/qfcc/include/symtab.h | 1 + tools/qfcc/source/class.c | 1 + tools/qfcc/source/emit.c | 1 + tools/qfcc/source/expr.c | 15 +++++++++++---- tools/qfcc/source/qc-lex.l | 2 +- tools/qfcc/source/qc-parse.y | 2 +- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index ce0741733..1ef20b399 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -54,6 +54,7 @@ typedef enum { sy_type, ///< symbol refers to a type sy_expr, ///< symbol refers to an expression sy_func, ///< symbol refers to a function + sy_class, ///< symbol refers to a class } sy_type_e; typedef struct symbol_s { diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index 0bc54dda2..46917e6b7 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -351,6 +351,7 @@ get_class (symbol_t *sym, int create) if (sym) { Hash_Add (class_hash, c); sym->type = c->type; + sym->sy_type = sy_class; } return c; } diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index 677a3e57d..b88fb2ec4 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -99,6 +99,7 @@ get_operand_def (expr_t *expr, operand_t *op) return get_value_def (&op->o.symbol->s.value, op->type); case sy_type: case sy_expr: + case sy_class: internal_error (expr, "invalid operand type"); } break; diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index ca5433f44..af3aa72b4 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2264,6 +2264,8 @@ is_lvalue (expr_t *e) return 0; case sy_func: return 0; + case sy_class: + return 0; } } if (e->type == ex_temp) @@ -2554,7 +2556,7 @@ message_expr (expr_t *receiver, keywordarg_t *message) int self = 0, super = 0, class_msg = 0; type_t *rec_type; type_t *return_type; - class_t *class; + class_t *class = 0; method_t *method; expr_t *send_msg; @@ -2572,8 +2574,11 @@ message_expr (expr_t *receiver, keywordarg_t *message) if (receiver->type == ex_symbol) { if (strcmp (receiver->e.symbol->name, "self") == 0) self = 1; - if (get_class (receiver->e.symbol, 0)) + if (receiver->e.symbol->sy_type == sy_class) { + class = receiver->e.symbol->type->t.class; class_msg = 1; + receiver = new_symbol_expr (class_pointer_symbol (class)); + } } rec_type = get_type (receiver); @@ -2586,11 +2591,13 @@ message_expr (expr_t *receiver, keywordarg_t *message) return error (receiver, "not a class/object"); if (self) { - class = extract_class (current_class); + if (!class) + class = extract_class (current_class); if (rec_type == class_Class.type) class_msg = 1; } else { - class = rec_type->t.class; + if (!class) + class = rec_type->t.class; } } diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 24d47540f..02492e6eb 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -365,7 +365,7 @@ keyword_or_id (char *token) yylval.symbol = sym; if (sym->sy_type == sy_type) return TYPE_NAME; - if (sym->type && is_class (sym->type)) + if (sym->sy_type == sy_class) return CLASS_NAME; return NAME; } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index e21726f90..845391f0b 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1569,7 +1569,7 @@ receiver : fexpr | CLASS_NAME { - $$ = new_symbol_expr (class_pointer_symbol ($1->type->t.class)); + $$ = new_symbol_expr ($1); } ;