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); }
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); }
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; }
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; }