/*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/* (C) 1998-2012, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 #include "nexttok.h"
 #include "scanner.h"
 #include "symbol.h"
-#include "symtab.h"
 
 
 
 
         /* Pass the scope back to the caller */
         SB_Append (FullName, Name);
-                               
+
         /* The scope must exist, so search for it starting with the current
          * scope.
          */
 
 
 
-SymEntry* ParseScopedSymName (int AllocNew)
+SymEntry* ParseScopedSymName (SymFindAction Action)
 /* Parse a (possibly scoped) symbol name, search for it in the symbol table
  * and return the symbol table entry.
  */
         /* Search for the symbol and return it. If no scope was specified,
          * search also in the upper levels.
          */
-        if (NoScope && !AllocNew) {
+        if (NoScope && (Action & SYM_ALLOC_NEW) == 0) {
             Sym = SymFindAny (Scope, &Ident);
         } else {
-            Sym = SymFind (Scope, &Ident, AllocNew);
+            Sym = SymFind (Scope, &Ident, Action);
         }
     } else {
         /* No scope ==> no symbol. To avoid errors in the calling routine that
-         * may not expect NULL to be returned if AllocNew is true, create a new
-         * symbol.
+         * may not expect NULL to be returned if Action contains SYM_ALLOC_NEW,
+         * create a new symbol.
          */
-        if (AllocNew) {
+        if (Action & SYM_ALLOC_NEW) { 
             Sym = NewSymEntry (&Ident, SF_NONE);
         } else {
             Sym = 0;
 
 
 
-SymEntry* ParseAnySymName (int AllocNew)
+SymEntry* ParseAnySymName (SymFindAction Action)
 /* Parse a cheap local symbol or a a (possibly scoped) symbol name, search
  * for it in the symbol table and return the symbol table entry.
  */
 
     /* Distinguish cheap locals and other symbols */
     if (CurTok.Tok == TOK_LOCAL_IDENT) {
-        Sym = SymFindLocal (SymLast, &CurTok.SVal, AllocNew);
+        Sym = SymFindLocal (SymLast, &CurTok.SVal, Action);
         NextTok ();
     } else {
-        Sym = ParseScopedSymName (AllocNew);
+        Sym = ParseScopedSymName (Action);
     }
 
     /* Return the symbol found */
 
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/* (C) 1998-2012, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 
 
 
+/* cc65 */
+#include "symtab.h"
+
+
+
 /*****************************************************************************/
 /*                                 Forwards                                  */
 /*****************************************************************************/
 
 
 struct StrBuf;
-struct SymTable;
 
 
 
  * by the caller for error messages or similar.
  */
 
-struct SymEntry* ParseScopedSymName (int AllowNew);
+struct SymEntry* ParseScopedSymName (SymFindAction Action);
 /* Parse a (possibly scoped) symbol name, search for it in the symbol table
  * and return the symbol table entry.
  */
  * symbol space and return the symbol table struct.
  */
 
-struct SymEntry* ParseAnySymName (int AllocNew);
+struct SymEntry* ParseAnySymName (SymFindAction Action);
 /* Parse a cheap local symbol or a a (possibly scoped) symbol name, search
  * for it in the symbol table and return the symbol table entry.
  */
 
 /* Combined values */
 #define SF_REFIMP       (SF_REFERENCED|SF_IMPORT)       /* A ref'd import */
 
-/* Arguments for SymFind... */
-#define SYM_FIND_EXISTING      0
-#define SYM_ALLOC_NEW          1
-
 /* Structure of a symbol table entry */
 typedef struct SymEntry SymEntry;
 struct SymEntry {
 
 
 
 
-SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, int AllocNew)
+SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, SymFindAction Action)
 /* Find a scope in the given enclosing scope */
 {
     SymTable** T = &Parent->Childs;
     }
 
     /* Create a new scope if requested and we didn't find one */
-    if (*T == 0 && AllocNew) {
+    if (*T == 0 && (Action & SYM_ALLOC_NEW) != 0) {
         *T = NewSymTable (Parent, Name);
     }
 
 
 
 
-SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, int AllocNew)
-/* Find a cheap local symbol. If AllocNew is given and the entry is not
- * found, create a new one. Return the entry found, or the new entry created,
- * or - in case AllocNew is zero - return 0.
+SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, SymFindAction Action)
+/* Find a cheap local symbol. If Action contains SYM_ALLOC_NEW and the entry is
+ * not found, create a new one. Return the entry found, or the new entry
+ * created, or - in case Action is SYM_FIND_EXISTING - return 0.
  */
+
 {
     SymEntry* S;
     int Cmp;
     if (!Parent) {
         /* No last global, so there's no local table */
         Error ("No preceeding global symbol");
-        if (AllocNew) {
+        if (Action & SYM_ALLOC_NEW) {
             return NewSymEntry (Name, SF_LOCAL);
         } else {
             return 0;
         return S;
     }
 
-    if (AllocNew) {
+    if (Action & SYM_ALLOC_NEW) {
 
         /* Otherwise create a new entry, insert and return it */
         SymEntry* N = NewSymEntry (Name, SF_LOCAL);
 
 
 
-SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew)
-/* Find a new symbol table entry in the given table. If AllocNew is given and
- * the entry is not found, create a new one. Return the entry found, or the
- * new entry created, or - in case AllocNew is zero - return 0.
+SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action)
+/* Find a new symbol table entry in the given table. If Action contains
+ * SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
+ * entry found, or the new entry created, or - in case Action is
+ * SYM_FIND_EXISTING - return 0.
  */
 {
     SymEntry* S;
 
     /* If we found an entry, return it */
     if (Cmp == 0) {
-        if (SymTabIsClosed (Scope)) {
+        if ((Action & SYM_CHECK_ONLY) == 0 && SymTabIsClosed (Scope)) {
             S->Flags |= SF_FIXED;
         }
         return S;
     }
 
-    if (AllocNew) {
+    if (Action & SYM_ALLOC_NEW) {
 
         /* Otherwise create a new entry, insert and return it. If the scope is
          * already closed, mark the symbol as fixed so it won't be resolved
  * never create a new symbol, since this can only be done in one specific
  * scope.
  */
-{                 
+{
     /* Generate the name hash */
     unsigned Hash = HashBuf (Name);
 
     if ((S->Flags & SF_FIXED) == 0) {
         SymTable* Tab = GetSymParentScope (S);
         while (Tab) {
-            Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING);
+            Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING | SYM_CHECK_ONLY);
             if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) {
                 /* We've found a symbol in a higher level that is
                  * either defined in the source, or an import.
 
 
 
 
+/* Arguments for SymFind... */
+typedef enum {
+    SYM_FIND_EXISTING  = 0x00,
+    SYM_ALLOC_NEW      = 0x01,
+    SYM_CHECK_ONLY      = 0x02,
+} SymFindAction;
+
 /* Symbol table flags */
 #define ST_NONE         0x00            /* No flags */
 #define ST_DEFINED      0x01            /* Scope has been defined */
 void SymLeaveLevel (void);
 /* Leave the current lexical level */
 
-SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, int AllocNew);
+SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, SymFindAction Action);
 /* Find a scope in the given enclosing scope */
 
 SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name);
  * scope.
  */
 
-SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* StrBuf, int AllocNew);
-/* Find a cheap local symbol. If AllocNew is given and the entry is not
- * found, create a new one. Return the entry found, or the new entry created,
- * or - in case AllocNew is zero - return 0.
+SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, SymFindAction Action);
+/* Find a cheap local symbol. If Action contains SYM_ALLOC_NEW and the entry is
+ * not found, create a new one. Return the entry found, or the new entry
+ * created, or - in case Action is SYM_FIND_EXISTING - return 0.
  */
 
-SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew);
-/* Find a new symbol table entry in the given table. If AllocNew is given and
- * the entry is not found, create a new one. Return the entry found, or the
- * new entry created, or - in case AllocNew is zero - return 0.
+SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, SymFindAction Action);
+/* Find a new symbol table entry in the given table. If Action contains
+ * SYM_ALLOC_NEW and the entry is not found, create a new one. Return the
+ * entry found, or the new entry created, or - in case Action is
+ * SYM_FIND_EXISTING - return 0.
  */
 
 SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name);