Type* ReplaceType (ExprDesc* Expr, const Type* NewType) /* Replace the type of Expr by a copy of Newtype and return the old type string */ { Type* OldType = Expr->Type; Expr->Type = TypeDup (NewType); return OldType; }
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; }
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; }
void ChangeSymType (SymEntry* Entry, Type* T) /* Change the type of the given symbol */ { TypeFree (Entry->Type); Entry->Type = TypeDup (T); }
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; }