예제 #1
0
파일: typecmp.c 프로젝트: JackieXie168/cc65
static int EqualSymTables (SymTable* Tab1, SymTable* Tab2)
/* Compare two symbol tables. Return 1 if they are equal and 0 otherwise */
{
    /* Compare the parameter lists */
    SymEntry* Sym1 = Tab1->SymHead;
    SymEntry* Sym2 = Tab2->SymHead;

    /* Compare the fields */
    while (Sym1 && Sym2) {

        /* Compare the names of this field */
        if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) {
            if (strcmp (Sym1->Name, Sym2->Name) != 0) {
                /* Names are not identical */
                return 0;
            }
        }

        /* Compare the types of this field */
        if (TypeCmp (Sym1->Type, Sym2->Type) < TC_EQUAL) {
            /* Field types not equal */
            return 0;
        }

        /* Get the pointers to the next fields */
        Sym1 = Sym1->NextSym;
        Sym2 = Sym2->NextSym;
    }

    /* Check both pointers against NULL to compare the field count */
    return (Sym1 == 0 && Sym2 == 0);
}
예제 #2
0
파일: typecmp.c 프로젝트: JackieXie168/cc65
static int EqualFuncParams (const FuncDesc* F1, const FuncDesc* F2)
/* Compare two function symbol tables regarding function parameters. Return 1
** if they are equal and 0 otherwise.
*/
{
    /* Get the symbol tables */
    const SymTable* Tab1 = F1->SymTab;
    const SymTable* Tab2 = F2->SymTab;

    /* Compare the parameter lists */
    const SymEntry* Sym1 = Tab1->SymHead;
    const SymEntry* Sym2 = Tab2->SymHead;

    /* Compare the fields */
    while (Sym1 && (Sym1->Flags & SC_PARAM) && Sym2 && (Sym2->Flags & SC_PARAM)) {

        /* Get the symbol types */
        Type* Type1 = Sym1->Type;
        Type* Type2 = Sym2->Type;

        /* If either of both functions is old style, apply the default
        ** promotions to the parameter type.
        */
        if (F1->Flags & FD_OLDSTYLE) {
            if (IsClassInt (Type1)) {
                Type1 = IntPromotion (Type1);
            }
        }
        if (F2->Flags & FD_OLDSTYLE) {
            if (IsClassInt (Type2)) {
                Type2 = IntPromotion (Type2);
            }
        }

        /* Compare this field */
        if (TypeCmp (Type1, Type2) < TC_EQUAL) {
            /* Field types not equal */
            return 0;
        }

        /* Get the pointers to the next fields */
        Sym1 = Sym1->NextSym;
        Sym2 = Sym2->NextSym;
    }

    /* Check both pointers against NULL or a non parameter to compare the
    ** field count
    */
    return (Sym1 == 0 || (Sym1->Flags & SC_PARAM) == 0) &&
           (Sym2 == 0 || (Sym2->Flags & SC_PARAM) == 0);
}
예제 #3
0
static void AliasAttr (const Declaration* D, DeclAttr* A)
/* Handle the "alias" attribute */
{
    SymEntry* Sym;

    /* Comma expected */
    ConsumeComma ();

    /* The next identifier is the name of the alias symbol */
    if (CurTok.Tok != TOK_IDENT) {
       	Error ("Identifier expected");
    	return;
    }

    /* Lookup the symbol for this name, it must exist */
    Sym = FindSym (CurTok.Ident);
    if (Sym == 0) {
    	Error ("Unknown identifier: `%s'", CurTok.Ident);
    	NextToken ();
    	return;
    }

    /* Since we have the symbol entry now, skip the name */
    NextToken ();

    /* Check if the types of the symbols are identical */
    if (TypeCmp (D->Type, Sym->Type) < TC_EQUAL) {
	/* Types are not identical */
	Error ("Incompatible types");
	return;
    }

    /* Attribute is verified, set the stuff in the attribute description */
    A->AttrType = atAlias;
    A->V.Sym	= Sym;
}
예제 #4
0
파일: symtab.c 프로젝트: doniexun/cc65
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;
}