Exemple #1
0
SymEntry* AddLabelSym (const char* Name, unsigned Flags)
/* Add a goto label to the label table */
{
    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name));
    if (Entry) {

        if (SymIsDef (Entry) && (Flags & SC_DEF) != 0) {
            /* Trying to define the label more than once */
            Error ("Label `%s' is defined more than once", Name);
        }
        Entry->Flags |= Flags;

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, SC_LABEL | Flags);

        /* Set a new label number */
        Entry->V.Label = GetLocalLabel ();

        /* Generate the assembler name of the label */
        Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label));

        /* Add the entry to the label table */
        AddSymEntry (LabelTab, Entry);

    }

    /* Return the entry */
    return Entry;
}
Exemple #2
0
SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val)
/* Add an constant symbol to the symbol table and return it */
{
    /* Enums must be inserted in the global symbol table */
    SymTable* Tab = ((Flags & SC_ENUM) == SC_ENUM)? SymTab0 : SymTab;

    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
    if (Entry) {
        if ((Entry->Flags & SC_CONST) != SC_CONST) {
            Error ("Symbol `%s' is already different kind", Name);
        } else {
            Error ("Multiple definition for `%s'", Name);
        }
        return Entry;
    }

    /* Create a new entry */
    Entry = NewSymEntry (Name, Flags);

    /* Enum values are ints */
    Entry->Type = TypeDup (T);

    /* Set the enum data */
    Entry->V.ConstVal = Val;

    /* Add the entry to the symbol table */
    AddSymEntry (Tab, Entry);

    /* Return the entry */
    return Entry;
}
Exemple #3
0
SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned Width)
/* Add a bit field to the local symbol table and return the symbol entry */
{
    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
    if (Entry) {

        /* We have a symbol with this name already */
        Error ("Multiple definition for `%s'", Name);

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, SC_BITFIELD);

        /* Set the symbol attributes. Bit-fields are always of type unsigned */
        Entry->Type         = type_uint;
        Entry->V.B.Offs     = Offs;
        Entry->V.B.BitOffs  = BitOffs;
        Entry->V.B.BitWidth = Width;

        /* Add the entry to the symbol table */
        AddSymEntry (SymTab, Entry);

    }

    /* Return the entry */
    return Entry;
}
Exemple #4
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;

    /* Local symbol, get the table */
    if (!Parent) {
        /* No last global, so there's no local table */
        Error ("No preceeding global symbol");
        if (Action & SYM_ALLOC_NEW) {
            return NewSymEntry (Name, SF_LOCAL);
        } else {
            return 0;
        }
    }

    /* Search for the symbol if we have a table */
    Cmp = SymSearchTree (Parent->Locals, Name, &S);

    /* If we found an entry, return it */
    if (Cmp == 0) {
        return S;
    }

    if (Action & SYM_ALLOC_NEW) {

        /* Otherwise create a new entry, insert and return it */
        SymEntry* N = NewSymEntry (Name, SF_LOCAL);
        N->Sym.Entry = Parent;
        if (S == 0) {
            Parent->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;
}
Exemple #5
0
SymEntry* ParseScopedSymName (SymFindAction Action)
/* Parse a (possibly scoped) symbol name, search for it in the symbol table
 * and return the symbol table entry.
 */
{
    StrBuf    ScopeName = STATIC_STRBUF_INITIALIZER;
    StrBuf    Ident = STATIC_STRBUF_INITIALIZER;
    int       NoScope;
    SymEntry* Sym;

    /* Parse the scoped symbol name */
    SymTable* Scope = ParseScopedIdent (&Ident, &ScopeName);

    /* If ScopeName is empty, no scope was specified */
    NoScope = SB_IsEmpty (&ScopeName);

    /* We don't need ScopeName any longer */
    SB_Done (&ScopeName);

    /* Check if the scope is valid. Errors have already been diagnosed by
     * the routine, so just exit.
     */
    if (Scope) {
        /* Search for the symbol and return it. If no scope was specified,
         * search also in the upper levels.
         */
        if (NoScope && (Action & SYM_ALLOC_NEW) == 0) {
            Sym = SymFindAny (Scope, &Ident);
        } else {
            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 Action contains SYM_ALLOC_NEW,
         * create a new symbol.
         */
        if (Action & SYM_ALLOC_NEW) { 
            Sym = NewSymEntry (&Ident, SF_NONE);
        } else {
            Sym = 0;
        }
    }

    /* Deallocate memory for ident */
    SB_Done (&Ident);

    /* Return the symbol found */
    return Sym;
}
Exemple #6
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;

    /* Global symbol: Get the hash value for the name */
    unsigned Hash = HashBuf (Name) % Scope->TableSlots;

    /* Search for the entry */
    int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);

    /* If we found an entry, return it */
    if (Cmp == 0) {
        if ((Action & SYM_CHECK_ONLY) == 0 && SymTabIsClosed (Scope)) {
            S->Flags |= SF_FIXED;
        }
        return S;
    }

    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
        ** by a symbol in the enclosing scopes later.
        */
        SymEntry* N = NewSymEntry (Name, SF_NONE);
        if (SymTabIsClosed (Scope)) {
            N->Flags |= SF_FIXED;
        }
        N->Sym.Tab = Scope;
        if (S == 0) {
            Scope->Table[Hash] = N;
        } else if (Cmp < 0) {
            S->Left = N;
        } else {
            S->Right = N;
        }
        ++Scope->TableEntries;
        return N;

    }

    /* We did not find the entry and AllocNew is false. */
    return 0;
}
Exemple #7
0
SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs)
/* Add a local symbol and return the symbol entry */
{
    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
    if (Entry) {

        /* We have a symbol with this name already */
        Error ("Multiple definition for `%s'", Name);

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, Flags);

        /* Set the symbol attributes */
        Entry->Type = TypeDup (T);
        if ((Flags & SC_AUTO) == SC_AUTO) {
            Entry->V.Offs = Offs;
        } else if ((Flags & SC_REGISTER) == SC_REGISTER) {
            Entry->V.R.RegOffs  = Offs;
            Entry->V.R.SaveOffs = StackPtr;
        } else if ((Flags & SC_EXTERN) == SC_EXTERN) {
            Entry->V.Label = Offs;
            SymSetAsmName (Entry);
        } else if ((Flags & SC_STATIC) == SC_STATIC) {
            /* Generate the assembler name from the label number */
            Entry->V.Label = Offs;
            Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label));
        } else if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD) {
            Entry->V.Offs = Offs;
        } else {
            Internal ("Invalid flags in AddLocalSym: %04X", Flags);
        }

        /* Add the entry to the symbol table */
        AddSymEntry (SymTab, Entry);

    }

    /* Return the entry */
    return Entry;
}
Exemple #8
0
SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab)
/* Add a struct/union entry and return it */
{
    SymEntry* Entry;

    /* Type must be struct or union */
    PRECONDITION (Type == SC_STRUCT || Type == SC_UNION);

    /* Do we have an entry with this name already? */
    Entry = FindSymInTable (TagTab, Name, HashStr (Name));
    if (Entry) {

        /* We do have an entry. This may be a forward, so check it. */
        if ((Entry->Flags & SC_TYPEMASK) != Type) {
            /* Existing symbol is not a struct */
            Error ("Symbol `%s' is already different kind", Name);
        } else if (Size > 0 && Entry->V.S.Size > 0) {
            /* Both structs are definitions. */
            Error ("Multiple definition for `%s'", Name);
        } else {
            /* Define the struct size if it is given */
            if (Size > 0) {
                Entry->V.S.SymTab = Tab;
                Entry->V.S.Size   = Size;
            }
        }

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, Type);

        /* Set the struct data */
        Entry->V.S.SymTab = Tab;
        Entry->V.S.Size   = Size;

        /* Add it to the current table */
        AddSymEntry (TagTab, Entry);
    }

    /* Return the entry */
    return Entry;
}
Exemple #9
0
SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
/* Add an external or global symbol to the symbol table and return the entry */
{
    /* There is some special handling for functions, so check if it is one */
    int IsFunc = IsTypeFunc (T);

    /* Functions must be inserted in the global symbol table */
    SymTable* Tab = IsFunc? SymTab0 : SymTab;

    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
    if (Entry) {

        Type* EType;

        /* We have a symbol with this name already */
        if (Entry->Flags & SC_TYPE) {
            Error ("Multiple definition for `%s'", Name);
            return Entry;
        }

        /* Get the type string of the existing symbol */
        EType = Entry->Type;

        /* If we are handling arrays, the old entry or the new entry may be an
        ** incomplete declaration. Accept this, and if the exsting entry is
        ** incomplete, complete it.
        */
        if (IsTypeArray (T) && IsTypeArray (EType)) {

            /* Get the array sizes */
            long Size  = GetElementCount (T);
            long ESize = GetElementCount (EType);

            if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
                TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
                /* Types not identical: Conflicting types */
                Error ("Conflicting types for `%s'", Name);
                return Entry;
            } else {
                /* Check if we have a size in the existing definition */
                if (ESize == UNSPECIFIED) {
                    /* Existing, size not given, use size from new def */
                    SetElementCount (EType, Size);
                }
            }

        } else {
            /* New type must be identical */
            if (TypeCmp (EType, T) < TC_EQUAL) {
                Error ("Conflicting types for `%s'", Name);
                return Entry;
            }

            /* In case of a function, use the new type descriptor, since it
            ** contains pointers to the new symbol tables that are needed if
            ** an actual function definition follows. Be sure not to use the
            ** new descriptor if it contains a function declaration with an
            ** empty parameter list.
            */
            if (IsFunc) {
                /* Get the function descriptor from the new type */
                FuncDesc* F = GetFuncDesc (T);
                /* Use this new function descriptor if it doesn't contain
                ** an empty parameter list.
                */
                if ((F->Flags & FD_EMPTY) == 0) {
                    Entry->V.F.Func = F;
                    SetFuncDesc (EType, F);
                }
            }
        }

        /* Add the new flags */
        Entry->Flags |= Flags;

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, Flags);

        /* Set the symbol attributes */
        Entry->Type = TypeDup (T);

        /* If this is a function, set the function descriptor and clear
        ** additional fields.
        */
        if (IsFunc) {
            Entry->V.F.Func = GetFuncDesc (Entry->Type);
            Entry->V.F.Seg  = 0;
        }

        /* Add the assembler name of the symbol */
        SymSetAsmName (Entry);

        /* Add the entry to the symbol table */
        AddSymEntry (Tab, Entry);
    }

    /* Return the entry */
    return Entry;
}