/* $Id: symbol.cc,v 1.4 1997/07/30 17:46:17 isis Exp $ */ // $Log: symbol.cc,v $ // Revision 1.4 1997/07/30 17:46:17 isis // Some minor new features and bug fixes // This seems to work fine // // Revision 1.3 1997/06/01 13:23:13 isis // Parsing of const: // e.g const char const * const a; // Changed the internal represantation of '*' to support const qualifiers // // Revision 1.2 1997/05/25 15:12:28 isis // Bug fixes // mostly with sizeof operator // // Revision 1.1.1.1 1997/05/18 12:15:40 isis // This is the initial distribution // of 'c-headers' using CVS // #include #include #include #include "Cname.h" #include "symbol.h" #include "h-fun.h" // Methods for class Scope Scope::Scope (Scope *enclos, char *szName, ErrorHandlerClass *eh, int nl) { EnclosingScope = enclos; ErrorHandler = eh; NestingLevel = nl; if ((ScopeName = strdup(szName)) == NULL) ErrorHandler->Internal("Not enough memory"); } ostream& Scope::Print(ostream& out) { MapType::iterator i; for(i=Entity.begin();i!=Entity.end();i++) { out << *((*i).second); } return out; } //******************************************************** Scope::~Scope (void) { // cout << "Scope killed\n"; } //******************************************************** ReturnCodes Scope::Insert(SymbolTableEntry* entry) { assert(entry!=NULL); entry->SetNestingLevel(NestingLevel+1); pair ret; MapType::value_type ins(entry->GetName(),entry); ret=Entity.insert(ins); if(ret.second==false) { char buf[80]; sprintf(buf,"Symbol Table: Symbol %s already inserted",entry->GetName()); ErrorHandler->Warning(buf); return DuplicateIdentifier; } ListEntity.push_back(entry); return OK; } void Scope::dummy1() { ListType::iterator i; for(i=ListEntity.begin();i!=ListEntity.end();i++) { (*i)=(*i); } } //******************************************************** SymbolTableEntry* Scope::Lookup(char* name, int mode) { MapType::iterator where; where=Entity.find(name); if(where != Entity.end()) return (*where).second; if (mode == SEARCH_CURRENT_SCOPE) return NULL; // If not found in current scope, search enclosing scopes recursively if (EnclosingScope != NULL) return EnclosingScope->Lookup(name); else return NULL; } //******************************************************** // Methods for class SymbolTableClass //******************************************************** SymbolTableClass::SymbolTableClass(ErrorHandlerClass *eh) { CurrentScope = NULL; SetErrorHandler(eh); } //******************************************************** SymbolTableClass::~SymbolTableClass(void) { while (CurrentScope != NULL) CloseScope(); } //******************************************************** void SymbolTableClass::OpenScope(char *szName) { if (CurrentScope == NULL) CurrentScope = new Scope(CurrentScope, szName, ErrorHandler, 0); else CurrentScope = new Scope(CurrentScope, szName, ErrorHandler, CurrentScope->GetNestingLevel()+1); if (CurrentScope == NULL) ErrorHandler->Internal("Not enough memory"); } //******************************************************** void SymbolTableClass::CloseScope(void) { CurrentScope = CurrentScope->GetEnclosing(); //delete tempScope; } Scope* SymbolTableClass::Up() { Scope *tmp=CurrentScope; CurrentScope = CurrentScope->GetEnclosing(); return tmp; } ostream& SymbolTableClass::Print(ostream&out) { CurrentScope->Print(out); return out; } //******************************************************** ReturnCodes SymbolTableClass::Insert(SymbolTableEntry *entry) { if (CurrentScope != NULL) return CurrentScope->Insert(entry); ErrorHandler->Internal("No current scope"); return OK; } //******************************************************** SymbolTableEntry *SymbolTableClass::Lookup(char *name, int mode) { return CurrentScope->Lookup(name, mode); } //******************************************************** int SymbolTableClass::GetNestingLevelOf(char *name) { SymbolTableEntry *tmp = CurrentScope->Lookup(name); if (tmp == NULL) ErrorHandler->Internal("Symbol not found during final code production."); return tmp->GetNestingLevel(); } //******************************************************** // Methods for class SymbolTableEntry SymbolTableEntry::SymbolTableEntry (char *name) { EntryName = strdup(name); } //******************************************************** SymbolTableEntry::~SymbolTableEntry () { assert(EntryName!=NULL); free(EntryName); // printf("Symbol destroyed\n");fflush(stdin); } //******************************************************** int SymbolTableEntry::operator == (SymbolTableEntry & entry) { return (strcmp(EntryName, entry.EntryName) == 0); } //******************************************************** int SymbolTableEntry::operator == (char *name) { return (strcmp(EntryName, name) == 0); } //******************************************************** // Methods for class VariableEntry //******************************************************** VariableEntry::VariableEntry(Cname* nam,Ctype* typ): SymbolTableEntry(clean_Cname(nam)) { c_name=nam; c_type=typ; //Let's calculate the alignment if(c_name->star_list!=NULL) alignment=sizeof(int *); else alignment=get_alignment_of_ctype(c_type); } VariableEntry::~VariableEntry() { // delete c_name; // delete c_type; } ostream& VariableEntry::Print(ostream& out) { if(c_name->function) out << "Function :'"; else out << "Variable (" << alignment << "):'"; out << GetName() << "'(" << *c_name << ',' << *c_type << ')' << endl; return out; } Cname* VariableEntry::GetCname() { return c_name; } Ctype* VariableEntry::GetCtype() { return c_type; } int VariableEntry::GetSize() { return get_sizeof_ctype_cname(c_type,c_name); } //******************************************************** // Methods for class TypeEntry //******************************************************** TypeEntry::TypeEntry(Cname*nam,Ctype*typ) : SymbolTableEntry(clean_Cname(nam)) { c_name=nam; c_type=typ; //WARNING:alignment and size is NOT declared here //to make forward declaration possibles.. } TypeEntry::TypeEntry(char *str,Ctype *typ) : SymbolTableEntry(str) { c_name=new Cname(0,str,0,NULL,NULL,false); c_type=typ; //WARNING:alignment and size is NOT declared here //to make forward declaration possibles.. } TypeEntry::TypeEntry(char *str,int sb,int al) : SymbolTableEntry(str) { c_name=new Cname(0,str,0,NULL,NULL,false); c_type=NULL; size_in_bytes=sb; alignment=al; } TypeEntry::~TypeEntry() { // delete c_name; // if(c_type) delete c_type; } Scope* TypeEntry::GetScope() { assert(c_type!=NULL); return c_type->GetScope(); } bool TypeEntry::IsSimple() { if(c_type==NULL) return true; return c_type->IsSimple(); } Ctype* TypeEntry::GetCtype() { return c_type; } Cname* TypeEntry::GetCname() { return c_name; } ostream& TypeEntry::Print(ostream&out) { out << "Type: (" << size_in_bytes << ") '" << GetName() << "'(" << *c_name; if(c_type != NULL) { out << ',' << *c_type; if(c_type->scope!=NULL) out << ',' << *(c_type->scope); } out << ')' << endl; return out; } //******************************************************** // Methods for class EnumEntry //******************************************************** EnumEntry::EnumEntry(gc_enum_id *en,Ctype *typ) : SymbolTableEntry(en->name) { enum_id=new gc_enum_id(*en); c_type=new Ctype(*typ); } ostream& EnumEntry::Print(ostream& out) { out << "Enum:'" << GetName() << "'(" << enum_id->value << ',' << *c_type << ')' << endl; return out; }