예제 #1
0
파일: objdata.c 프로젝트: cc65/cc65
void ClearObjData (ObjData* O)
/* Remove any data stored in O */
{
    unsigned I;
    xfree (O->Name);
    O->Name = 0;
    for (I = 0; I < CollCount (&O->Strings); ++I) {
        xfree (CollAt (&O->Strings, I));
    }
    CollDeleteAll (&O->Strings);
    CollDeleteAll (&O->Exports);
}
예제 #2
0
파일: symentry.c 프로젝트: Aliandrana/cc65
static void SymReplaceExprRefs (SymEntry* S)
/* Replace the references to this symbol by a copy of the symbol expression */
{
    unsigned I;
    long     Val;

    /* Check if the expression is const and get its value */
    int IsConst = IsConstExpr (S->Expr, &Val);
    CHECK (IsConst);

    /* Loop over all references */
    for (I = 0; I < CollCount (&S->ExprRefs); ++I) {

        /* Get the expression node */
        ExprNode* E = CollAtUnchecked (&S->ExprRefs, I);

        /* Safety */
        CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == S);

        /* We cannot touch the root node, since there are pointers to it.
        ** Replace it by a literal node.
        */
        E->Op = EXPR_LITERAL;
        E->V.IVal = Val;
    }

    /* Remove all symbol references from the symbol */
    CollDeleteAll (&S->ExprRefs);
}
예제 #3
0
void CS_DelLabel (CodeSeg* S, CodeLabel* L)
/* Remove references from this label and delete it. */
{
    unsigned Count, I;

    /* First, remove the label from the hash chain */
    CS_RemoveLabelFromHash (S, L);

    /* Remove references from insns jumping to this label */
    Count = CollCount (&L->JumpFrom);
    for (I = 0; I < Count; ++I) {
       	/* Get the insn referencing this label */
       	CodeEntry* E = CollAt (&L->JumpFrom, I);
       	/* Remove the reference */
       	CE_ClearJumpTo (E);
    }
    CollDeleteAll (&L->JumpFrom);

    /* Remove the reference to the owning instruction if it has one. The
     * function may be called for a label without an owner when deleting
     * unfinished parts of the code. This is unfortunate since it allows
     * errors to slip through.
     */
    if (L->Owner) {
       	CollDeleteItem (&L->Owner->Labels, L);
    }

    /* All references removed, delete the label itself */
    FreeCodeLabel (L);
}
예제 #4
0
static void CS_MoveLabelsToPool (CodeSeg* S, CodeEntry* E)
/* Move the labels of the code entry E to the label pool of the code segment */
{
    unsigned LabelCount = CE_GetLabelCount (E);
    while (LabelCount--) {
   	CodeLabel* L = CE_GetLabel (E, LabelCount);
	L->Owner = 0;
	CollAppend (&S->Labels, L);
    }
    CollDeleteAll (&E->Labels);
}
예제 #5
0
파일: input.c 프로젝트: eakmeister/cc65
void ClearLine (void)
/* Clear the current input line */
{
    unsigned I;

    /* Remove all pushed fragments from the input stack */
    for (I = 0; I < CollCount (&InputStack); ++I) {
        FreeStrBuf (CollAtUnchecked (&InputStack, I));
    }
    CollDeleteAll (&InputStack);

    /* Clear the contents of Line */
    SB_Clear (Line);
    CurC    = '\0';
    NextC   = '\0';
}
예제 #6
0
static void CS_MoveLabelsToEntry (CodeSeg* S, CodeEntry* E)
/* Move all labels from the label pool to the given entry and remove them
 * from the pool.
 */
{
    /* Transfer the labels if we have any */
    unsigned I;
    unsigned LabelCount = CollCount (&S->Labels);
    for (I = 0; I < LabelCount; ++I) {

   	/* Get the label */
   	CodeLabel* L = CollAt (&S->Labels, I);

   	/* Attach it to the entry */
   	CE_AttachLabel (E, L);
    }

    /* Delete the transfered labels */
    CollDeleteAll (&S->Labels);
}
예제 #7
0
파일: symentry.c 프로젝트: Aliandrana/cc65
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);
}
예제 #8
0
파일: symtab.c 프로젝트: Aliandrana/cc65
static void SymCheckUndefined (SymEntry* S)
/* Handle an undefined symbol */
{
    /* Undefined symbol. It may be...
    **
    **   - An undefined symbol in a nested lexical level. If the symbol is not
    **     fixed to this level, search for the symbol in the higher levels and
    **     make the entry a trampoline entry if we find one.
    **
    **   - If the symbol is not found, it is a real undefined symbol. If the
    **     AutoImport flag is set, make it an import. If the AutoImport flag is
    **     not set, it's an error.
    */
    SymEntry* Sym = 0;
    if ((S->Flags & SF_FIXED) == 0) {
        SymTable* Tab = GetSymParentScope (S);
        while (Tab) {
            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.
                */
                 break;
            }
            /* No matching symbol found in this level. Look further */
            Tab = Tab->Parent;
        }
    }

    if (Sym) {

        /* 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 import */
                LIError (&S->RefLines,
                         "Symbol `%s' is already an import",
                         GetString (Sym->Name));
            }
            if ((Sym->Flags & SF_EXPORT) == 0) {
                /* 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 */
                    LIWarning (&Sym->DefLines, 1,
                               "Symbol `%m%p' is %s but exported %s",
                               GetSymName (Sym),
                               AddrSizeToStr (Sym->AddrSize),
                               AddrSizeToStr (Sym->ExportSize));
                }
            }
        }
        if (S->Flags & SF_REFERENCED) {
            /* Mark as referenced and move the line info */
            Sym->Flags |= SF_REFERENCED;
            CollTransfer (&Sym->RefLines, &S->RefLines);
            CollDeleteAll (&S->RefLines);
        }

        /* Transfer all expression references */
        SymTransferExprRefs (S, Sym);

        /* Mark the symbol as unused removing all other flags */
        S->Flags = SF_UNUSED;

    } else {
        /* The symbol is definitely undefined */
        if (S->Flags & SF_EXPORT) {
            /* We will not auto-import an export */
            LIError (&S->RefLines,
                     "Exported symbol `%m%p' was never defined",
                     GetSymName (S));
        } else {
            if (AutoImport) {
                /* Mark as import, will be indexed later */
                S->Flags |= SF_IMPORT;
                /* Use the address size for code */
                S->AddrSize = CodeAddrSize;
                /* Mark point of import */
                GetFullLineInfo (&S->DefLines);
            } else {
                /* Error */
                LIError (&S->RefLines,
                         "Symbol `%m%p' is undefined",
                         GetSymName (S));
            }
        }
    }
}