]> git.sur5r.net Git - cc65/commitdiff
Emit warnings for symbols that were used suboptimal because of forward
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 9 Apr 2006 10:56:23 +0000 (10:56 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 9 Apr 2006 10:56:23 +0000 (10:56 +0000)
definitions. For example a zero page symbol that is used as absolute because
it was undefined when encountered.

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

src/ca65/expr.c
src/ca65/expr.h
src/ca65/instr.c
src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c

index 86729c02101e9b8c0960414a6ed2e1f7ac5fc2ee..f9258c5313ec3d4699e2f84a23a8c5b696970e4d 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
+/* (C) 1998-2006 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -1695,11 +1695,11 @@ void WriteExpr (ExprNode* Expr)
 
         case EXPR_LITERAL:
             ObjWrite8 (EXPR_LITERAL);
-           ObjWrite32 (Expr->V.Val);
-           break;
+           ObjWrite32 (Expr->V.Val);
+           break;
 
         case EXPR_SYMBOL:
-           if (SymIsImport (Expr->V.Sym)) {
+           if (SymIsImport (Expr->V.Sym)) {
                 ObjWrite8 (EXPR_SYMBOL);
                 ObjWriteVar (GetSymIndex (Expr->V.Sym));
             } else {
@@ -1728,4 +1728,41 @@ void WriteExpr (ExprNode* Expr)
 
 
 
+void ExprGuessedAddrSize (const ExprNode* Expr, unsigned char AddrSize)
+/* Mark the address size of the given expression tree as guessed. The address
+ * size passed as argument is the one NOT used, because the actual address
+ * size wasn't known. Example: Zero page addressing was not used because symbol
+ * is undefined, and absolute addressing was available.
+ * This function will actually parse the expression tree for undefined symbols,
+ * and mark these symbols accordingly.
+ */
+{
+    /* Accept NULL expressions */
+    if (Expr == 0) {
+        return;
+    }
+
+    /* Check the type code */
+    switch (Expr->Op & EXPR_TYPEMASK) {
+
+        case EXPR_LEAFNODE:
+            if (Expr->Op == EXPR_SYMBOL) {
+                if (!SymIsDef (Expr->V.Sym)) {
+                    /* Symbol is undefined, mark it */
+                    SymGuessedAddrSize (Expr->V.Sym, AddrSize);
+                }
+            }
+            return;
+
+        case EXPR_BINARYNODE:
+            ExprGuessedAddrSize (Expr->Right, AddrSize);
+            /* FALLTHROUGH */
+
+        case EXPR_UNARYNODE:
+            ExprGuessedAddrSize (Expr->Left, AddrSize);
+            break;
+    }
+}
+
+
 
index 4e6c7988d4871a3eab674c6805c9623841c0eb45..43a70a09e5cf064b1ab044024c1b2e68f56c4cca 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/* (C) 1998-2006 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -137,6 +137,15 @@ ExprNode* CloneExpr (ExprNode* Expr);
 void WriteExpr (ExprNode* Expr);
 /* Write the given expression to the object file */
 
+void ExprGuessedAddrSize (const ExprNode* Expr, unsigned char AddrSize);
+/* Mark the address size of the given expression tree as guessed. The address
+ * size passed as argument is the one NOT used, because the actual address
+ * size wasn't known. Example: Zero page addressing was not used because symbol
+ * is undefined, and absolute addressing was available.
+ * This function will actually parse the expression tree for undefined symbols,
+ * and mark these symbols accordingly.
+ */
+
 
 
 /* End of expr.h */
index bebc0ae9b384e7389d5b80a33e280dc4845cb2c8..89cdaf5e873fb3353e156af79bb606f096305151 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2005, Ullrich von Bassewitz                                      */
+/* (C) 1998-2006, Ullrich von Bassewitz                                      */
 /*                Römerstrasse 52                                            */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -946,11 +946,19 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
         /* Simplify it if possible */
         A->Expr = SimplifyExpr (A->Expr, &ED);
 
-        /* If we don't know how big the expression is, assume the default
-         * address size for data.
-         */
         if (ED.AddrSize == ADDR_SIZE_DEFAULT) {
+            /* If we don't know how big the expression is, assume the
+             * default address size for data. If this default address
+             * size is unequal to zero page addressing, but zero page
+             * addressing is allowed by the instruction, mark all symbols
+             * in the expression tree. This mark will be checked at end
+             * of assembly, and a warning is issued, if a zero page symbol
+             * was guessed wrong here.
+             */
             ED.AddrSize = DataAddrSize;
+            if (ED.AddrSize > ADDR_SIZE_ZP && (A->AddrModeSet & AM65_SET_ZP)) {
+                ExprGuessedAddrSize (A->Expr, ADDR_SIZE_ZP);
+            }
         }
 
         /* Check the size */
index 8fcd5c0a505dbd7e4238ea106bfc73d543527166..077ddd0d35b1ff55a811d9b3f7ea5f2156e7d4bf 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
+/* (C) 1998-2006 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -75,16 +75,21 @@ SymEntry* SymLast = 0;
 SymEntry* NewSymEntry (const char* Name, unsigned Flags)
 /* Allocate a symbol table entry, initialize and return it */
 {
+    unsigned I;
+
     /* Allocate memory */
     SymEntry* S = xmalloc (sizeof (SymEntry));
 
     /* Initialize the entry */
-    S->Left      = 0;
-    S->Right     = 0;
-    S->Locals    = 0;
-    S->SymTab    = 0;
-    S->Pos       = CurPos;
-    S->Flags     = Flags;
+    S->Left              = 0;
+    S->Right             = 0;
+    S->Locals            = 0;
+    S->SymTab            = 0;
+    S->Pos               = CurPos;
+    for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
+        S->GuessedUse[I] = 0;
+    }
+    S->Flags             = Flags;
     S->Expr       = 0;
     S->ExprRefs   = AUTO_COLLECTION_INITIALIZER;
     S->ExportSize = ADDR_SIZE_DEFAULT;
@@ -193,7 +198,7 @@ static void SymReplaceExprRefs (SymEntry* S)
         /* Safety */
         CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == S);
 
-        /* We cannot touch the root node, since there are pointers to it. 
+        /* We cannot touch the root node, since there are pointers to it.
          * Replace it by a literal node.
          */
         E->Op = EXPR_LITERAL;
@@ -252,7 +257,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
     /* Set the symbol value */
     S->Expr = Expr;
 
-    /* In case of a variable symbol, walk over all expressions containing 
+    /* In case of a variable symbol, walk over all expressions containing
      * this symbol and replace the (sub-)expression by the literal value of
      * the tree. Be sure to replace the expression node in place, since there
      * may be pointers to it.
@@ -549,6 +554,32 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
 
 
 
+void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize)
+/* Mark the address size of the given symbol as guessed. The address size
+ * passed as argument is the one NOT used, because the actual address size
+ * wasn't known. Example: Zero page addressing was not used because symbol
+ * is undefined, and absolute addressing was available.
+ */
+{
+    /* We must have a valid address size passed */
+    PRECONDITION (AddrSize != ADDR_SIZE_DEFAULT);
+
+    /* We do not support all address sizes currently */
+    if (AddrSize > sizeof (Sym->GuessedUse) / sizeof (Sym->GuessedUse[0])) {
+        return;
+    }
+
+    /* We can only remember one such occurance */
+    if (Sym->GuessedUse[AddrSize-1]) {
+        return;
+    }
+
+    /* Ok, remember the file position */
+    Sym->GuessedUse[AddrSize-1] = xdup (&CurPos, sizeof (CurPos));
+}
+
+
+
 void SymExportFromGlobal (SymEntry* S)
 /* Called at the end of assembly. Converts a global symbol that is defined
  * into an export.
index a5d745dd8a73fc8bc0752521f86d0517e84da2eb..b30d07241299bfaa2cc8b6973ab64e8230ee80f2 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
+/* (C) 1998-2006 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /* Structure of a symbol table entry */
 typedef struct SymEntry SymEntry;
 struct SymEntry {
-    SymEntry*                      Left;       /* Lexically smaller entry */
-    SymEntry*                      Right;      /* Lexically larger entry */
-    SymEntry*                      List;       /* List of all entries */
-    SymEntry*                      Locals;     /* Root of subtree for local symbols */
-    struct SymTable*       SymTab;     /* Table this symbol is in, 0 for locals */
-    FilePos                        Pos;        /* File position for this symbol */
-    unsigned                Flags;     /* Symbol flags */
-    unsigned               Index;      /* Index of import/export entries */
-    struct ExprNode*        Expr;              /* Symbol expression */
-    Collection              ExprRefs;   /* Expressions using this symbol */
-    unsigned char           ExportSize; /* Export address size */
-    unsigned char           AddrSize;   /* Address size of label */
-    unsigned char                  ConDesPrio[CD_TYPE_COUNT];  /* ConDes priorities... */
+    SymEntry*                  Left;           /* Lexically smaller entry */
+    SymEntry*                  Right;          /* Lexically larger entry */
+    SymEntry*                  List;           /* List of all entries */
+    SymEntry*                  Locals;         /* Root of subtree for local symbols */
+    struct SymTable*   SymTab;         /* Table this symbol is in, 0 for locals */
+    FilePos                    Pos;            /* File position for this symbol */
+    FilePos*            GuessedUse[1];  /* File position where symbol
+                                         * address size was guessed, and the
+                                         * smallest possible addressing was NOT
+                                         * used. Currently only for zero page
+                                         * addressing
+                                         */
+    unsigned            Flags;         /* Symbol flags */
+    unsigned           Index;          /* Index of import/export entries */
+    struct ExprNode*    Expr;          /* Symbol expression */
+    Collection          ExprRefs;       /* Expressions using this symbol */
+    unsigned char       ExportSize;     /* Export address size */
+    unsigned char       AddrSize;       /* Address size of label */
+    unsigned char              ConDesPrio[CD_TYPE_COUNT];      /* ConDes priorities... */
                                        /* ...actually value+1 (used as flag) */
-    unsigned                Name;              /* Name index in global string pool */
+    unsigned            Name;          /* Name index in global string pool */
 };
 
 /* List of all symbol table entries */
@@ -166,6 +172,13 @@ void SymConDes (SymEntry* Sym, unsigned char AddrSize, unsigned Type, unsigned P
  * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 
+void SymGuessedAddrSize (SymEntry* Sym, unsigned char AddrSize);
+/* Mark the address size of the given symbol as guessed. The address size
+ * passed as argument is the one NOT used, because the actual address size
+ * wasn't known. Example: Zero page addressing was not used because symbol
+ * is undefined, and absolute addressing was available.
+ */
+
 void SymExportFromGlobal (SymEntry* S);
 /* Called at the end of assembly. Converts a global symbol that is defined
  * into an export.
index ec853248c276ffdce85e1148177b3498c4e9d23a..8193fe33cc287fa1f43afdae726629ed8ab73f31 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
+/* (C) 1998-2006 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -600,6 +600,25 @@ void SymCheck (void)
                 }
                 ED_Done (&ED);
             }
+
+            /* If the address size of the symbol was guessed, check the guess
+             * against the actual address size and print a warning if the two
+             * differ.
+             */
+            if (S->AddrSize != ADDR_SIZE_DEFAULT) {
+                /* Do we have data for this address size? */
+                if (S->AddrSize <= sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0])) {
+                    /* Get the file position where the symbol was used */
+                    const FilePos* P = S->GuessedUse[S->AddrSize - 1];
+                    if (P) {
+                        PWarning (P, 0,
+                                  "Didn't use %s addressing for `%s'",
+                                  AddrSizeToStr (S->AddrSize),
+                                  GetSymName (S));
+                    }
+                }
+            }
+
        }
 
        /* Next symbol */