Example #1
0
void SetElementCount (Type* T, long Count)
/* Set the element count of the array specified in T (which must be of
** array type).
*/
{
    CHECK (IsTypeArray (T));
    T->A.L = Count;
}
Example #2
0
long GetElementCount (const Type* T)
/* Get the element count of the array specified in T (which must be of
** array type).
*/
{
    CHECK (IsTypeArray (T));
    return T->A.L;
}
Example #3
0
Type* GetBaseElementType (Type* T)
/* Return the base element type of a given type. If T is not an array, this
** will return. Otherwise it will return the base element type, which means
** the element type that is not an array.
*/
{
    while (IsTypeArray (T)) {
        ++T;
    }
    return T;
}
Example #4
0
Type* PtrConversion (Type* T)
/* If the type is a function, convert it to pointer to function. If the
** expression is an array, convert it to pointer to first element. Otherwise
** return T.
*/
{
    if (IsTypeFunc (T)) {
        return PointerTo (T);
    } else if (IsTypeArray (T)) {
        return ArrayToPtr (T);
    } else {
        return T;
    }
}
Example #5
0
static long ArrayElementCount (const ArgDesc* Arg)
/* Check if the type of the given argument is an array. If so, and if the
 * element count is known, return it. In all other cases, return UNSPECIFIED.
 */
{
    long Count;

    if (IsTypeArray (Arg->Type)) {
        Count = GetElementCount (Arg->Type);
        if (Count == FLEXIBLE) {
            /* Treat as unknown */
            Count = UNSPECIFIED;
        }
    } else {
        Count = UNSPECIFIED;
    }
    return Count;
}
Example #6
0
Type* GetElementType (Type* T)
/* Return the element type of the given array type. */
{
    CHECK (IsTypeArray (T));
    return T + 1;
}
Example #7
0
int TypeHasAttr (const Type* T)
/* Return true if the given type has attribute data */
{
    return IsClassStruct (T) || IsTypeArray (T) || IsClassFunc (T);
}
Example #8
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;
}