]> git.sur5r.net Git - cc65/commitdiff
Don't use SF_TRAMPOLINE, change symbol references instead.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 29 Nov 2003 07:53:26 +0000 (07:53 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 29 Nov 2003 07:53:26 +0000 (07:53 +0000)
In smart mode, use RTL instead of RTS if the enclosing .PROC is far.
More address size changes.

git-svn-id: svn://svn.cc65.org/cc65/trunk@2696 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
src/ca65/expr.c
src/ca65/instr.c
src/ca65/main.c
src/ca65/nexttok.c
src/ca65/pseudo.c
src/ca65/pseudo.h
src/ca65/scanner.c
src/ca65/scanner.h
src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c
src/ca65/symtab.h

index dcb2f681e862a3c7b20d8966e4f529ad988c955f..3af3ea3099f245b6cc5e79d7b39ae70b853b9eea 100644 (file)
@@ -534,11 +534,31 @@ static ExprNode* Function (ExprNode* (*F) (void))
 
 
 
+static ExprNode* Symbol (SymEntry* S)
+/* Reference a symbol and return an expression for it */
+{
+    if (S == 0) {
+        /* Some weird error happened before */
+        return GenLiteralExpr (0);
+    } else {
+        /* Mark the symbol as referenced */
+        SymRef (S);
+        /* Remove the symbol if possible */
+        if (SymHasExpr (S)) {
+            return CloneExpr (GetSymExpr (S));
+        } else {
+            /* Create symbol node */
+            return GenSymExpr (S);
+        }
+    }
+}
+
+
+
 static ExprNode* Factor (void)
 {
     ExprNode* L;
     ExprNode* N;
-    SymEntry* S;
     long      Val;
 
     switch (Tok) {
@@ -555,24 +575,14 @@ static ExprNode* Factor (void)
 
        case TOK_NAMESPACE:
        case TOK_IDENT:
-           /* Search for the symbol */
-           S = ParseScopedSymName (SYM_ALLOC_NEW);
-           if (S == 0) {
-               /* Some weird error happened before */
-               N = GenLiteralExpr (0);
-           } else {
-               /* Mark the symbol as referenced */
-               SymRef (S);
-                /* Remove the symbol if possible */
-                if (SymHasExpr (S)) {
-                    N = CloneExpr (GetSymExpr (S));
-                } else {
-                    /* Create symbol node */
-                    N = GenSymExpr (S);
-                }
-           }
+            N = Symbol (ParseScopedSymName (SYM_ALLOC_NEW));
            break;
 
+        case TOK_LOCAL_IDENT:
+            N = Symbol (SymFindLocal (SVal, SYM_ALLOC_NEW));
+            NextTok ();
+            break;
+
        case TOK_ULABEL:
            N = ULabRef (IVal);
            NextTok ();
index f5dfff89b79b2672e2affe161736fe7b6ae0477f..4c5d667860538f292e3d05aa95665ab04f4fab9f 100644 (file)
@@ -38,7 +38,9 @@
 #include <ctype.h>
 
 /* common */
+#include "addrsize.h"
 #include "assertdefs.h"
+#include "attrib.h"
 #include "bitops.h"
 #include "check.h"
 
@@ -69,7 +71,8 @@ static void PutBlockMove (const InsDesc* Ins);
 static void PutBitBranch (const InsDesc* Ins);
 static void PutREP (const InsDesc* Ins);
 static void PutSEP (const InsDesc* Ins);
-static void PutJmp (const InsDesc* Ins);
+static void PutJMP (const InsDesc* Ins);
+static void PutRTS (const InsDesc* Ins);
 static void PutAll (const InsDesc* Ins);
 
 
@@ -109,7 +112,7 @@ static const struct {
                { "INC",  0x000006c, 0x00, 4, PutAll },
                { "INX",  0x0000001, 0xe8, 0, PutAll },
                { "INY",  0x0000001, 0xc8, 0, PutAll },
-               { "JMP",  0x0000808, 0x4c, 6, PutJmp },
+               { "JMP",  0x0000808, 0x4c, 6, PutJMP },
                { "JSR",  0x0000008, 0x20, 7, PutAll },
                { "LDA",  0x080A26C, 0xa0, 0, PutAll },
                { "LDX",  0x080030C, 0xa2, 1, PutAll },
@@ -403,7 +406,7 @@ static const struct {
                { "ROR",  0x000006F, 0x62, 1, PutAll },
                { "RTI",  0x0000001, 0x40, 0, PutAll },
                { "RTL",  0x0000001, 0x6b, 0, PutAll },
-               { "RTS",  0x0000001, 0x60, 0, PutAll },
+               { "RTS",  0x0000001, 0x60, 0, PutRTS },
                { "SBC",  0x0b8f6fc, 0xe0, 0, PutAll },
                { "SEC",  0x0000001, 0x38, 0, PutAll },
                { "SED",  0x0000001, 0xf8, 0, PutAll },
@@ -788,7 +791,7 @@ static void PutSEP (const InsDesc* Ins)
 
 
 
-static void PutJmp (const InsDesc* Ins)
+static void PutJMP (const InsDesc* Ins)
 /* Handle the jump instruction for the 6502. Problem is that these chips have
  * a bug: If the address crosses a page, the upper byte gets not corrected and
  * the instruction will fail. The PutJmp function will add a linker assertion
@@ -823,6 +826,20 @@ static void PutJmp (const InsDesc* Ins)
 
 
 
+static void PutRTS (const InsDesc* Ins attribute ((unused)))
+/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
+ * the enclosing scope is FAR.
+ */
+{
+    if (SmartMode && CurrentScope->AddrSize == ADDR_SIZE_FAR) {
+        Emit0 (0x6B);       /* RTL */
+    } else {
+        Emit0 (0x60);       /* RTS */
+    }
+}
+
+
+
 static void PutAll (const InsDesc* Ins)
 /* Handle all other instructions */
 {
index 31c92a19898938f3d772b5fe46ad2399f0537795..9a159a1a4332a569f05a66237190a9abdf7103a4 100644 (file)
@@ -390,63 +390,58 @@ static void OneLine (void)
     }
 
     /* Assemble the line */
-    if (Tok == TOK_IDENT) {
+    if (Tok == TOK_LOCAL_IDENT || (Tok == TOK_IDENT && !IsMacro (SVal))) {
 
-       /* Is it a macro? */
-       if (IsMacro (SVal)) {
+        /* Did we have whitespace before the ident? */
+        int HadWS = WS;
 
-           /* Yes, start a macro expansion */
-           MacExpandStart ();
-           Done = 1;
-
-       } else {
-
-           /* No, label. Remember the identifier, then skip it */
-           int HadWS = WS;     /* Did we have whitespace before the ident? */
-
-           /* Generate the symbol table entry, then skip the name */
-           SymEntry* Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
-           NextTok ();
-
-           /* If a colon follows, this is a label definition. If there
-            * is no colon, it's an assignment.
-            */
-                   if (Tok == TOK_EQ || Tok == TOK_ASSIGN) {
-                /* If it's an assign token, we have a label */
-                unsigned Flags = (Tok == TOK_ASSIGN)? SF_LABEL : SF_NONE;
-               /* Skip the '=' */
-               NextTok ();
-               /* Define the symbol with the expression following the '=' */
-               SymDef (Sym, Expression(), ADDR_SIZE_DEFAULT, Flags);
-               /* Don't allow anything after a symbol definition */
-               Done = 1;
-           } else {
-               /* Define a label */
-                       SymDef (Sym, GenCurrentPC (), ADDR_SIZE_DEFAULT, SF_LABEL);
-               /* Skip the colon. If NoColonLabels is enabled, allow labels
-                * without a colon if there is no whitespace before the
-                * identifier.
-                */
-               if (Tok != TOK_COLON) {
-                   if (HadWS || !NoColonLabels) {
-                       Error ("`:' expected");
-                   }
-                   if (Tok == TOK_NAMESPACE) {
-                       /* Smart :: handling */
-                       NextTok ();
-                   }
-               } else {
-                   /* Skip the colon */
-                   NextTok ();
-               }
-           }
-       }
+        /* Generate the symbol table entry, then skip the name */
+        SymEntry* Sym;
+        if (Tok == TOK_IDENT) {
+            Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
+        } else {
+            Sym = SymFindLocal (SVal, SYM_ALLOC_NEW);
+        }
+        NextTok ();
+
+        /* If a colon follows, this is a label definition. If there
+         * is no colon, it's an assignment.
+         */
+        if (Tok == TOK_EQ || Tok == TOK_ASSIGN) {
+            /* If it's an assign token, we have a label */
+            unsigned Flags = (Tok == TOK_ASSIGN)? SF_LABEL : SF_NONE;
+            /* Skip the '=' */
+            NextTok ();
+            /* Define the symbol with the expression following the '=' */
+            SymDef (Sym, Expression(), ADDR_SIZE_DEFAULT, Flags);
+            /* Don't allow anything after a symbol definition */
+            Done = 1;
+        } else {
+            /* Define a label */
+            SymDef (Sym, GenCurrentPC (), ADDR_SIZE_DEFAULT, SF_LABEL);
+            /* Skip the colon. If NoColonLabels is enabled, allow labels
+             * without a colon if there is no whitespace before the
+             * identifier.
+             */
+            if (Tok != TOK_COLON) {
+                if (HadWS || !NoColonLabels) {
+                    Error ("`:' expected");
+                    /* Try some smart error recovery */
+                    if (Tok == TOK_NAMESPACE) {
+                        NextTok ();
+                    }
+                }
+            } else {
+                /* Skip the colon */
+                NextTok ();
+            }
+        }
     }
 
     if (!Done) {
 
-       if (TokIsPseudo (Tok)) {
-           /* A control command, IVal is index into table */
+       if (Tok >= TOK_FIRSTPSEUDO && Tok <= TOK_LASTPSEUDO) {
+           /* A control command */
            HandlePseudo ();
        } else if (Tok == TOK_MNEMO) {
            /* A mnemonic - assemble one instruction */
@@ -670,7 +665,7 @@ int main (int argc, char* argv [])
 
     /* If no memory model was given, use the default */
     if (MemoryModel == MMODEL_UNKNOWN) {
-        MemoryModel = MMODEL_NEAR;
+        SetMemoryModel (MMODEL_NEAR);
     }
 
     /* Intialize the target translation tables */
index 5be1dfc8a19473ee8c30443ac746686e4ec62a44..0b1fbcd2a87ef70dd9333a51f1f517e2fe7309a3 100644 (file)
@@ -339,7 +339,7 @@ static void FuncString (void)
     ConsumeLParen ();
 
     /* Accept identifiers or numeric expressions */
-    if (Tok == TOK_IDENT) {
+    if (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) {
        /* Save the identifier, then skip it */
        strcpy (Buf, SVal);
        NextTok ();
index b7059a7fee8c4db2171035d1bf6d260aee2f0ee2..8a277b955fb960bdae8537c26c01fa34872d180e 100644 (file)
@@ -1736,14 +1736,6 @@ static CtrlDesc CtrlCmdTab [] = {
 
 
 
-int TokIsPseudo (unsigned Tok)
-/* Return true if the given token is a pseudo instruction token */
-{
-    return (Tok >= TOK_FIRSTPSEUDO && Tok <= TOK_LASTPSEUDO);
-}
-
-
-
 void HandlePseudo (void)
 /* Handle a pseudo instruction */
 {
index b9ebd3164e60f41baca69aefef19017a91d96e6b..40ff9df383d6916657786d3bda964b800c99fda1 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstraße 52                                              */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -58,9 +58,6 @@ extern unsigned OpenIfs;
 
 
 
-int TokIsPseudo (unsigned Tok);
-/* Return true if the given token is a pseudo instruction token */
-
 void HandlePseudo (void);
 /* Handle a pseudo instruction */
 
index 56aadd74c873b3533e60085f10fc217926b25ae5..d06e3d0e7427d40fa5a3751f5a937bdbcabc9084 100644 (file)
@@ -769,8 +769,8 @@ Again:
                    goto Again;
        }
 
-               /* An identifier */
-       Tok = TOK_IDENT;
+               /* A local identifier */
+       Tok = TOK_LOCAL_IDENT;
        return;
     }
 
@@ -1098,7 +1098,7 @@ CharAgain:
 int TokHasSVal (enum Token Tok)
 /* Return true if the given token has an attached SVal */
 {
-    return (Tok == TOK_IDENT || Tok == TOK_STRCON);
+    return (Tok == TOK_IDENT || TOK_LOCAL_IDENT || Tok == TOK_STRCON);
 }
 
 
@@ -1127,7 +1127,7 @@ int GetSubKey (const char** Keys, unsigned Count)
     if (!IgnoreCase) {
        UpcaseSVal ();
     }
-
+                         
     /* Do a linear search (a binary search is not worth the effort) */
     for (I = 0; I < Count; ++I) {
        if (strcmp (SVal, Keys [I]) == 0) {
index 71084168c89331610065381f6cdbbba0e3e08bcc..c958e24640f02d393be1f3d7cc91db7fde068718 100644 (file)
@@ -56,6 +56,7 @@ enum Token {
     TOK_EOF,                   /* End of input file */
     TOK_SEP,           /* Separator (usually newline) */
     TOK_IDENT,         /* An identifier */
+    TOK_LOCAL_IDENT,    /* A cheap local identifier */
     TOK_MNEMO,                 /* A mnemonic */
 
     TOK_INTCON,        /* Integer constant */
@@ -214,7 +215,7 @@ enum Token {
     TOK_RODATA,
     TOK_SCOPE,
     TOK_SEGMENT,
-    TOK_SETCPU, 
+    TOK_SETCPU,
     TOK_SIZEOF,
     TOK_SMART,
     TOK_STRAT,
index 6f67ec015d4b4df607f26d9ef228b267164ce8ef..257265101bbfa07e29f2648f930de49e95f2b8cd 100644 (file)
@@ -177,6 +177,32 @@ void SymRef (SymEntry* S)
 
 
 
+void SymTransferExprRefs (SymEntry* From, SymEntry* To)
+/* Transfer all expression references from one symbol to another. */
+{
+    unsigned I;
+
+    for (I = 0; I < CollCount (&From->ExprRefs); ++I) {
+
+        /* Get the expression node */
+        ExprNode* E = CollAtUnchecked (&From->ExprRefs, I);
+
+        /* Safety */
+        CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == From);
+
+        /* Replace the symbol reference */
+        E->V.Sym = To;
+
+        /* Add the expression reference */
+        SymAddExprRef (To, E);
+    }
+
+    /* Remove all symbol references from the old symbol */
+    CollDeleteAll (&From->ExprRefs);
+}
+
+
+
 void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags)
 /* Define a new symbol */
 {
@@ -248,12 +274,6 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
 void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 /* Mark the given symbol as an imported symbol */
 {
-    /* Don't accept local symbols */
-    if (IsLocalNameId (S->Name)) {
-       Error ("Illegal use of a local symbol");
-       return;
-    }
-
     if (S->Flags & SF_DEFINED) {
        Error ("Symbol `%s' is already defined", GetSymName (S));
        S->Flags |= SF_MULTDEF;
@@ -300,12 +320,6 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
 /* Mark the given symbol as an exported symbol */
 {
-    /* Don't accept local symbols */
-    if (IsLocalNameId (S->Name)) {
-       Error ("Illegal use of a local symbol");
-       return;
-    }
-
     /* Check if it's ok to export the symbol */
     if (S->Flags & SF_IMPORT) {
        /* The symbol is already marked as imported external symbol */
@@ -359,12 +373,6 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
  * either imported or exported.
  */
 {
-    /* Don't accept local symbols */
-    if (IsLocalNameId (S->Name)) {
-       Error ("Illegal use of a local symbol");
-       return;
-    }
-
     /* If the symbol is already marked as import, the address size must match.
      * Apart from that, ignore the global declaration.
      */
@@ -456,12 +464,6 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
 #endif
     CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
 
-    /* Don't accept local symbols */
-    if (IsLocalNameId (S->Name)) {
-               Error ("Illegal use of a local symbol");
-               return;
-    }
-
     /* Check for errors */
     if (S->Flags & SF_IMPORT) {
                /* The symbol is already marked as imported external symbol */
@@ -509,116 +511,20 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
 
 
 
-int SymIsDef (const SymEntry* S)
-/* Return true if the given symbol is already defined */
-{
-    return (S->Flags & SF_DEFINED) != 0;
-}
-
-
-
-int SymIsRef (const SymEntry* S)
-/* Return true if the given symbol has been referenced */
-{
-    return (S->Flags & SF_REFERENCED) != 0;
-}
-
-
-
-int SymIsImport (const SymEntry* S)
-/* Return true if the given symbol is marked as import */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
-    /* Check the import flag */
-    return (S->Flags & SF_IMPORT) != 0;
-}
-
-
-
 int SymIsConst (SymEntry* S, long* Val)
 /* Return true if the given symbol has a constant value. If Val is not NULL
  * and the symbol has a constant value, store it's value there.
  */
 {
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
     /* Check for constness */
     return (SymHasExpr (S) && IsConstExpr (S->V.Expr, Val));
 }
 
 
 
-int SymHasExpr (const SymEntry* S)
-/* Return true if the given symbol has an associated expression */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
-    /* Check the expression */
-    return ((S->Flags & (SF_DEFINED|SF_IMPORT)) == SF_DEFINED);
-}
-
-
-
-void SymMarkUser (SymEntry* S)
-/* Set a user mark on the specified symbol */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-               S = S->V.Sym;
-    }
-
-    /* Set the bit */
-    S->Flags |= SF_USER;
-}
-
-
-
-void SymUnmarkUser (SymEntry* S)
-/* Remove a user mark from the specified symbol */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
-    /* Reset the bit */
-    S->Flags &= ~SF_USER;
-}
-
-
-
-int SymHasUserMark (SymEntry* S)
-/* Return the state of the user mark for the specified symbol */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
-    /* Check the bit */
-    return (S->Flags & SF_USER) != 0;
-}
-
-
-
 struct ExprNode* GetSymExpr (SymEntry* S)
 /* Get the expression for a non-const symbol */
 {
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
     PRECONDITION (S != 0 && SymHasExpr (S));
     return S->V.Expr;
 }
@@ -630,41 +536,11 @@ const struct ExprNode* SymResolve (const SymEntry* S)
  * NULL. Do not call in other contexts!
  */
 {
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
     return SymHasExpr (S)? S->V.Expr : 0;
 }
 
 
 
-const char* GetSymName (const SymEntry* S)
-/* Return the name of the symbol */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-    return GetString (S->Name);
-}
-
-
-
-unsigned char GetSymAddrSize (const SymEntry* S)
-/* Return the address size of the symbol. Beware: This function will just
- * return the AddrSize member, it will not look at the expression!
- */
-{
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-    return S->AddrSize;
-}
-
-
-
 long GetSymVal (SymEntry* S)
 /* Return the value of a symbol assuming it's constant. FAIL will be called
  * in case the symbol is undefined or not constant.
@@ -680,27 +556,9 @@ long GetSymVal (SymEntry* S)
 unsigned GetSymIndex (const SymEntry* S)
 /* Return the symbol index for the given symbol */
 {
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
     PRECONDITION (S != 0 && (S->Flags & SF_INDEXED) != 0);
     return S->Index;
 }
 
 
 
-const FilePos* GetSymPos (const SymEntry* S)
-/* Return the position of first occurence in the source for the given symbol */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-    PRECONDITION (S != 0);
-    return &S->Pos;
-}
-
-
-
-
index a7b3bf3306cc5d55f442d1ad1f4ff0fe237a40ff..ce342a83029a402f854d583b4b7cf82bdd4a2e38 100644 (file)
 #include "cddefs.h"
 #include "coll.h"
 #include "filepos.h"
+#include "inline.h"
+
+/* ca65 */
+#include "spool.h"
 
 
 
@@ -54,7 +58,7 @@
 /* Bits for the Flags value in SymEntry */
 #define SF_NONE         0x0000          /* Empty flag set */
 #define SF_USER                0x0001          /* User bit */
-#define SF_TRAMPOLINE          0x0002          /* Trampoline entry */
+#define SF_UNUSED       0x0002         /* Unused entry */
 #define SF_EXPORT              0x0004          /* Export this symbol */
 #define SF_IMPORT      0x0008          /* Import this symbol */
 #define SF_GLOBAL      0x0010          /* Global symbol */
@@ -145,6 +149,9 @@ INLINE void SymDelExprRef (SymEntry* Sym, struct ExprNode* Expr)
 #define SymDelExprRef(Sym,Expr)     CollDeleteItem (&(Sym)->ExprRefs, Expr)
 #endif
 
+void SymTransferExprRefs (SymEntry* From, SymEntry* To);
+/* Transfer all expression references from one symbol to another. */
+
 void SymDef (SymEntry* Sym, ExprNode* Expr, unsigned char AddrSize, unsigned Flags);
 /* Mark a symbol as defined */
 
@@ -167,31 +174,85 @@ void SymConDes (SymEntry* Sym, unsigned char AddrSize, unsigned Type, unsigned P
  * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 
-int SymIsDef (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE int SymIsDef (const SymEntry* S)
 /* Return true if the given symbol is already defined */
+{
+    return (S->Flags & SF_DEFINED) != 0;
+}
+#else
+#  define SymIsDef(S)   (((S)->Flags & SF_DEFINED) != 0)
+#endif
 
-int SymIsRef (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE int SymIsRef (const SymEntry* S)
 /* Return true if the given symbol has been referenced */
+{
+    return (S->Flags & SF_REFERENCED) != 0;
+}
+#else
+#  define SymIsRef(S)   (((S)->Flags & SF_REFERENCED) != 0)
+#endif
 
-int SymIsImport (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE int SymIsImport (const SymEntry* S)
 /* Return true if the given symbol is marked as import */
+{
+    /* Check the import flag */
+    return (S->Flags & SF_IMPORT) != 0;
+}
+#else
+#  define SymIsImport(S)  (((S)->Flags & SF_IMPORT) != 0)
+#endif
 
 int SymIsConst (SymEntry* Sym, long* Val);
 /* Return true if the given symbol has a constant value. If Val is not NULL
  * and the symbol has a constant value, store it's value there.
  */
 
-int SymHasExpr (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE int SymHasExpr (const SymEntry* S)
 /* Return true if the given symbol has an associated expression */
+{
+    /* Check the expression */
+    return ((S->Flags & (SF_DEFINED|SF_IMPORT)) == SF_DEFINED);
+}
+#else
+#  define SymHasExpr(S)   (((S)->Flags & (SF_DEFINED|SF_IMPORT)) != SF_DEFINED)
+#endif
 
-void SymMarkUser (SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE void SymMarkUser (SymEntry* S)
 /* Set a user mark on the specified symbol */
+{
+    /* Set the bit */
+    S->Flags |= SF_USER;
+}
+#else
+#  define SymMarkUser(S)   ((S)->Flags |= SF_USER)
+#endif
 
-void SymUnmarkUser (SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE void SymUnmarkUser (SymEntry* S)
 /* Remove a user mark from the specified symbol */
+{
+    /* Reset the bit */
+    S->Flags &= ~SF_USER;
+}
+#else
+#  define SymUnmarkUser(S)   ((S)->Flags &= ~SF_USER)
+#endif
 
-int SymHasUserMark (SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE int SymHasUserMark (SymEntry* S)
 /* Return the state of the user mark for the specified symbol */
+{
+    /* Check the bit */
+    return (S->Flags & SF_USER) != 0;
+}
+#else
+#  define SymHasUserMark(S) (((S)->Flags & SF_USER) != 0)
+#endif
 
 struct ExprNode* GetSymExpr (SymEntry* Sym);
 /* Get the expression for a non-const symbol */
@@ -201,13 +262,27 @@ const struct ExprNode* SymResolve (const SymEntry* Sym);
  * NULL. Do not call in other contexts!
  */
 
-const char* GetSymName (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE const char* GetSymName (const SymEntry* S)
 /* Return the name of the symbol */
+{
+    return GetString (S->Name);
+}
+#else
+#  define GetSymName(S)   GetString ((S)->Name)
+#endif
 
-unsigned char GetSymAddrSize (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE unsigned char GetSymAddrSize (const SymEntry* S)
 /* Return the address size of the symbol. Beware: This function will just
  * return the AddrSize member, it will not look at the expression!
  */
+{
+    return S->AddrSize;
+}
+#else
+#  define GetSymAddrSize(S)   ((S)->AddrSize)
+#endif
 
 long GetSymVal (SymEntry* Sym);
 /* Return the value of a symbol assuming it's constant. FAIL will be called
@@ -217,9 +292,15 @@ long GetSymVal (SymEntry* Sym);
 unsigned GetSymIndex (const SymEntry* Sym);
 /* Return the symbol index for the given symbol */
 
-const FilePos* GetSymPos (const SymEntry* Sym);
+#if defined(HAVE_INLINE)
+INLINE const FilePos* GetSymPos (const SymEntry* S)
 /* Return the position of first occurence in the source for the given symbol */
-
+{
+    return &S->Pos;
+}
+#else
+#  define GetSymPos(S)   (&(S)->Pos)
+#endif
 
 
 
index bf6a3da817e896f9b1209820cbae399d93036d14..674d925907d95d97575f7d4167ebeba175251ac6 100644 (file)
@@ -64,9 +64,7 @@
 /* Combined symbol entry flags used within this module */
 #define SF_UNDEFMASK   (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
 #define SF_UNDEFVAL    (SF_REFERENCED)
-#define SF_EXPMASK     (SF_TRAMPOLINE | SF_EXPORT)
-#define SF_EXPVAL      (SF_EXPORT)
-#define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
+#define SF_DBGINFOMASK         (SF_UNUSED | SF_DEFINED | SF_EXPORT | SF_IMPORT)
 #define SF_DBGINFOVAL  (SF_DEFINED)
 
 /* Symbol tables */
@@ -74,8 +72,8 @@ SymTable*             CurrentScope = 0;       /* Pointer to current symbol table */
 SymTable*      RootScope    = 0;       /* Root symbol table */
 
 /* Symbol table variables */
-static unsigned                ImportCount = 0;/* Counter for import symbols */
-static unsigned        ExportCount = 0;/* Counter for export symbols */
+static unsigned ImportCount = 0;        /* Counter for import symbols */
+static unsigned ExportCount = 0;        /* Counter for export symbols */
 
 
 
@@ -257,85 +255,88 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name)
 
 
 
-SymEntry* SymFind (SymTable* Scope, const char* 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* SymFindLocal (const char* 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* S;
     int Cmp;
 
-    if (IsLocalName (Name)) {
+    /* Local symbol, get the table */
+    if (!SymLast) {
+        /* No last global, so there's no local table */
+        Error ("No preceeding global symbol");
+        if (AllocNew) {
+            return NewSymEntry (Name);
+        } else {
+            return 0;
+        }
+    }
 
-       /* Local symbol, get the table */
-       if (!SymLast) {
-           /* No last global, so there's no local table */
-           Error ("No preceeding global symbol");
-           if (AllocNew) {
-               return NewSymEntry (Name);
-           } else {
-               return 0;
-           }
-               }
+    /* Search for the symbol if we have a table */
+    Cmp = SymSearchTree (SymLast->Locals, Name, &S);
 
-       /* Search for the symbol if we have a table */
-        Cmp = SymSearchTree (SymLast->Locals, Name, &S);
+    /* If we found an entry, return it */
+    if (Cmp == 0) {
+        return S;
+    }
 
-       /* If we found an entry, return it */
-       if (Cmp == 0) {
-           return S;
-       }
+    if (AllocNew) {
 
-       if (AllocNew) {
+        /* Otherwise create a new entry, insert and return it */
+        SymEntry* N = NewSymEntry (Name);
+        if (S == 0) {
+            SymLast->Locals = N;
+        } else if (Cmp < 0) {
+            S->Left = N;
+        } else {
+            S->Right = N;
+        }
+        return N;
+    }
 
-           /* Otherwise create a new entry, insert and return it */
-           SymEntry* N = NewSymEntry (Name);
-           if (S == 0) {
-               SymLast->Locals = N;
-           } else if (Cmp < 0) {
-               S->Left = N;
-           } else {
-               S->Right = N;
-           }
-           return N;
-       }
+    /* We did not find the entry and AllocNew is false. */
+    return 0;
+}
 
-    } else {
 
-       /* Global symbol: Get the hash value for the name */
-               unsigned Hash = HashStr (Name) % Scope->TableSlots;
 
-       /* Search for the entry */
-       Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
+SymEntry* SymFind (SymTable* Scope, const char* 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* S;
 
-       /* If we found an entry, return it */
-       if (Cmp == 0) {
-           /* Check for a trampoline entry, in this case return the real
-            * symbol.
-            */
-           while (S->Flags & SF_TRAMPOLINE) {
-               S = S->V.Sym;
-           }
-            return S;
-       }
+    /* Global symbol: Get the hash value for the name */
+    unsigned Hash = HashStr (Name) % Scope->TableSlots;
 
-       if (AllocNew) {
+    /* Search for the entry */
+    int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
 
-           /* Otherwise create a new entry, insert and return it */
-           SymEntry* N = NewSymEntry (Name);
-           if (S == 0) {
-               Scope->Table[Hash] = N;
-           } else if (Cmp < 0) {
-               S->Left = N;
-           } else {
-               S->Right = N;
-           }
-                   N->SymTab = Scope;
-           ++Scope->TableEntries;
-           return N;
+    /* If we found an entry, return it */
+    if (Cmp == 0) {
+        return S;
+    }
+
+    if (AllocNew) {
+
+        /* Otherwise create a new entry, insert and return it */
+        SymEntry* N = NewSymEntry (Name);
+        if (S == 0) {
+            Scope->Table[Hash] = N;
+        } else if (Cmp < 0) {
+            S->Left = N;
+        } else {
+            S->Right = N;
+        }
+        N->SymTab = Scope;
+        ++Scope->TableEntries;
+        return N;
 
-       }
     }
 
     /* We did not find the entry and AllocNew is false. */
@@ -372,11 +373,6 @@ static SymEntry* SymFindAny (SymTable* Scope, const char* Name)
 int SymIsZP (SymEntry* S)
 /* Return true if the symbol is explicitly marked as zeropage symbol */
 {
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
     /* If the symbol is not a global symbol, was not defined before, check the
      * enclosing scope for a symbol with the same name, and return the ZP
      * attribute of this symbol if we find one.
@@ -443,28 +439,50 @@ static void SymCheckUndefined (SymEntry* S)
            }
        }
     }
+
     if (Sym) {
-       /* We found the symbol in a higher level. Make S a trampoline
-        * symbol. Beware: We have to transfer the symbol attributes to
-        * the real symbol and check for any conflicts.
-        */
-       S->Flags |= SF_TRAMPOLINE;
-       S->V.Sym = Sym;
 
-       /* Transfer the flags. Note: S may not be imported, since in that
-        * case it wouldn't be undefined.
-        */
-               if (S->Flags & SF_EXPORT) {
+        /* We found the symbol in a higher level. Transfer the flags and
+         * address size from the local symbol to that in the higher level
+         * and check for problems.
+         */
+        if (S->Flags & SF_EXPORT) {
            if (Sym->Flags & SF_IMPORT) {
-               /* The symbol is already marked as imported external symbol */
-               PError (&S->Pos, "Symbol `%s' is already an import", GetString (S->Name));
+               /* The symbol is already marked as import */
+               PError (&S->Pos, "Symbol `%s' is already an import",
+                        GetString (Sym->Name));
            }
-           Sym->Flags |= (S->Flags & SF_EXPORT);
-            Sym->ExportSize = S->ExportSize;
-       }
+            if (Sym->Flags & SF_EXPORT) {
+                /* The symbol is already marked as an export. */
+                if (Sym->AddrSize > S->ExportSize) {
+                    /* We're exporting a symbol smaller than it actually is */
+                    PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
+                              GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
+                              AddrSizeToStr (S->ExportSize));
+                }
+            } else {
+                /* Mark the symbol as an export */
+                Sym->Flags |= SF_EXPORT;
+                Sym->ExportSize = S->ExportSize;
+                if (Sym->ExportSize == ADDR_SIZE_DEFAULT) {
+                    /* Use the actual size of the symbol */
+                    Sym->ExportSize = Sym->AddrSize;
+                }
+                if (Sym->AddrSize > Sym->ExportSize) {
+                    /* We're exporting a symbol smaller than it actually is */
+                    PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
+                              GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
+                              AddrSizeToStr (Sym->ExportSize));
+                }
+            }
+        }
+        Sym->Flags |= (S->Flags & SF_REFERENCED);
+
+        /* Transfer all expression references */
+        SymTransferExprRefs (S, Sym);
 
-       /* Transfer the referenced flag */
-       Sym->Flags |= (S->Flags & SF_REFERENCED);
+        /* Mark the symbol as unused removing all other flags */
+        S->Flags = SF_UNUSED;
 
     } else {
        /* The symbol is definitely undefined */
@@ -474,12 +492,12 @@ static void SymCheckUndefined (SymEntry* S)
                     GetString (S->Name));
        } else {
            if (AutoImport) {
-               /* Mark as import, will be indexed later */
-               S->Flags |= SF_IMPORT;
+               /* Mark as import, will be indexed later */
+               S->Flags |= SF_IMPORT;
                 /* Use the address size for code */
                 S->AddrSize = CodeAddrSize;
            } else {
-               /* Error */
+               /* Error */
                PError (&S->Pos, "Symbol `%s' is undefined", GetString (S->Name));
            }
        }
@@ -509,9 +527,9 @@ void SymCheck (void)
        if (S->Flags & SF_GLOBAL) {
            S->Flags &= ~SF_GLOBAL;
            if (S->Flags & SF_DEFINED) {
-               S->Flags |= SF_EXPORT;
+               S->Flags |= SF_EXPORT;
            } else {
-               S->Flags |= SF_IMPORT;
+               S->Flags |= SF_IMPORT;
            }
        }
 
@@ -526,35 +544,35 @@ void SymCheck (void)
     }
 
     /* Second pass: Walk again through the symbols. Ignore undefined's, since
-     * we handled them in the last pass, and ignore trampoline symbols, since
+     * we handled them in the last pass, and ignore unused symbols, since
      * we handled them in the last pass, too.
      */
     S = SymList;
     while (S) {
-       if ((S->Flags & SF_TRAMPOLINE) == 0 &&
+       if ((S->Flags & SF_UNUSED) == 0 &&
            (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
            if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
-               /* Symbol was defined but never referenced */
-               PWarning (&S->Pos, 2,
+               /* Symbol was defined but never referenced */
+               PWarning (&S->Pos, 2,
                           "Symbol `%s' is defined but never used",
                           GetString (S->Name));
            }
            if (S->Flags & SF_IMPORT) {
-               if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
-                   /* Imported symbol is not referenced */
-                   PWarning (&S->Pos, 2,
+               if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
+                   /* Imported symbol is not referenced */
+                   PWarning (&S->Pos, 2,
                               "Symbol `%s' is imported but never used",
                               GetString (S->Name));
-               } else {
-                   /* Give the import an index, count imports */
-                   S->Index = ImportCount++;
-                   S->Flags |= SF_INDEXED;
-               }
+               } else {
+                   /* Give the import an index, count imports */
+                   S->Index = ImportCount++;
+                   S->Flags |= SF_INDEXED;
+               }
            }
            if (S->Flags & SF_EXPORT) {
-               /* Give the export an index, count exports */
-               S->Index = ExportCount++;
-               S->Flags |= SF_INDEXED;
+               /* Give the export an index, count exports */
+               S->Index = ExportCount++;
+               S->Flags |= SF_INDEXED;
            }
        }
 
@@ -571,8 +589,8 @@ void SymDump (FILE* F)
     SymEntry* S = SymList;
 
     while (S) {
-       /* Ignore trampoline symbols */
-       if ((S->Flags & SF_TRAMPOLINE) != 0) {
+       /* Ignore unused symbols */
+       if ((S->Flags & SF_UNUSED) != 0) {
            fprintf (F,
                     "%-24s %s %s %s %s %s\n",
                     GetString (S->Name),
@@ -607,7 +625,7 @@ void WriteImports (void)
      */
     S = SymList;
     while (S) {
-        if ((S->Flags & (SF_TRAMPOLINE | SF_IMPORT)) == SF_IMPORT &&
+        if ((S->Flags & (SF_UNUSED | SF_IMPORT)) == SF_IMPORT &&
             (S->Flags & (SF_REFERENCED | SF_FORCED)) != 0) {
 
             ObjWrite8 (S->AddrSize);
@@ -638,7 +656,7 @@ void WriteExports (void)
     /* Walk throught list and write all exports to the file */
     S = SymList;
     while (S) {
-               if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
+               if ((S->Flags & (SF_UNUSED | SF_EXPORT)) == SF_EXPORT) {
 
             long ConstVal;
 
index 20aa2a354f2b4ccf22f18901829f05bd1721d5ce..bc32a2c793ed7f481b0304d4fa5aa8c9e0f5ac8e 100644 (file)
@@ -111,6 +111,12 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name);
  * scope.
  */
 
+SymEntry* SymFindLocal (const char* 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* SymFind (SymTable* Scope, const char* 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