void ParseEnumerationList(TABLE *table) { int evalue; SYM *sp; evalue = 0; while(lastst == id) { sp = allocSYM(); sp->SetName(*(new std::string(lastid))); sp->storage_class = sc_const; sp->tp = &stdconst; table->insert(sp); NextToken(); if (lastst==assign) { NextToken(); sp->value.i = GetIntegerExpression((ENODE **)NULL); evalue = (int)sp->value.i+1; } else sp->value.i = evalue++; if( lastst == comma) NextToken(); else if(lastst != end) break; } needpunc(end,48); }
Statement *ParseFirstcallStatement() { Statement *snp; SYM *sp; int st; dfs.puts("<ParseFirstcall>"); snp = NewStatement(st_firstcall, TRUE); sp = allocSYM(); // sp->SetName(*(new std::string(snp->fcname))); sp->storage_class = sc_static; sp->value.i = nextlabel++; sp->tp = &stdbyte; st = lastst; lastst = kw_firstcall; // fake out doinit() doinit(sp); lastst = st; // doinit should set realname snp->fcname = my_strdup(sp->realname); snp->s1 = ParseStatement(); // Empty statements return NULL if (snp->s1) snp->s1->outer = snp; dfs.puts("</ParseFirstcall>"); return snp; }
void ParseEnumerationList(TABLE *table) { int evalue; SYM *sp; evalue = 0; while(lastst == id) { sp = allocSYM(); sp->name = litlate(lastid); sp->storage_class = sc_const; sp->tp = &stdconst; insert(sp,table); NextToken(); if (lastst==assign) { NextToken(); sp->value.i = GetIntegerExpression((ENODE **)NULL); evalue = sp->value.i+1; } else sp->value.i = evalue++; if( lastst == comma) NextToken(); else if(lastst != end) break; } needpunc(end); }
Statement *ParseLabelStatement() { Statement *snp; SYM *sp; snp = NewStatement(st_label, FALSE); if( (sp = search(lastid,&lsyms)) == NULL ) { sp = allocSYM(); sp->name = litlate(lastid); sp->storage_class = sc_label; sp->tp = 0; sp->value.i = nextlabel++; insert(sp,&lsyms); } else { if( sp->storage_class != sc_ulabel ) error(ERR_LABEL); else sp->storage_class = sc_label; } NextToken(); /* get past id */ needpunc(colon); if( sp->storage_class == sc_label ) { snp->label = sp->value.i; snp->next = NULL; return snp; } return 0; }
Statement *ParseGotoStatement() { Statement *snp; SYM *sp; NextToken(); if( lastst != id ) { error(ERR_IDEXPECT); return NULL; } snp = NewStatement(st_goto, FALSE); if( (sp = search(lastid,&lsyms)) == NULL ) { sp = allocSYM(); sp->name = litlate(lastid); sp->value.i = nextlabel++; sp->storage_class = sc_ulabel; sp->tp = 0; insert(sp,&lsyms); } NextToken(); /* get past label name */ if( lastst != end ) needpunc( semicolon ); if( sp->storage_class != sc_label && sp->storage_class != sc_ulabel) error( ERR_LABEL ); else { snp->stype = st_goto; snp->label = sp->value.i; snp->next = NULL; return snp; } return NULL; }
//struct snode *interrupt_stmt() //{ struct snode *snp; // SYM *sp; // TYP *temp1; // // NextToken(); // if( lastst != id ) { // error(ERR_IDEXPECT); // return 0; // } // sp = allocSYM(); // sp->name = litlate(lastid); // sp->value.i = nextlabel++; // sp->storage_class = sc_global; // sp->tp = temp1; // temp1 = maketype(bt_long,0); // temp1->val_flag = 1; // insert(sp,&lsyms); // NextToken(); /* get past label name */ // needpunc( colon ); // snp = (struct snode *)xalloc(sizeof(struct snode)); // snp->stype = st_interrupt; // snp->label = sp->name; // snp->next = 0; // snp->s1 = statement(); // return snp; //} // struct snode *vortex_stmt() { struct snode *snp; SYM *sp; TYP *temp1; NextToken(); if( lastst != id ) { error(ERR_IDEXPECT); return 0; } temp1 = maketype(bt_long,0); temp1->val_flag = 1; sp = allocSYM(); sp->name = litlate(lastid); sp->value.i = nextlabel++; sp->storage_class = sc_global; sp->tp = temp1; insert(sp,&lsyms); NextToken(); /* get past label name */ needpunc( colon ); snp = (struct snode *)xalloc(sizeof(struct snode)); snp->stype = st_vortex; snp->label = sp->name; snp->next = 0; snp->s1 = ParseStatement(); return snp; }
Statement *vortex_stmt() { Statement *snp; SYM *sp; TYP *temp1; NextToken(); if( lastst != id ) { error(ERR_IDEXPECT); return 0; } temp1 = TYP::Make(bt_long,0); temp1->val_flag = 1; sp = allocSYM(); sp->SetName(*(new std::string(lastid))); sp->value.i = nextlabel++; sp->storage_class = sc_global; sp->SetType(temp1); currentFn->lsyms.insert(sp); NextToken(); /* get past label name */ needpunc( colon,30 ); snp = (struct snode *)xalloc(sizeof(struct snode)); snp->stype = st_vortex; snp->label = (int64_t *)my_strdup((char *)sp->name->c_str()); snp->next = 0; snp->s1 = ParseStatement(); return snp; }
int dodefine() { SYM *sp; NextToken(); /* get past #define */ if( lastst != id ) { error(ERR_DEFINE); return getline(incldepth == 0); } ++global_flag; /* always do #define as globals */ sp = allocSYM(); sp->name = litlate(lastid); sp->value.s = litlate(lptr-1); insert(sp,&defsyms); --global_flag; return getline(incldepth == 0); }
SYM *makeint(char *name) { SYM *sp; TYP *tp; sp = allocSYM(); tp = TYP::Make(bt_long,8); tp->sname = new std::string(""); tp->isUnsigned = FALSE; tp->isVolatile = FALSE; sp->SetName(name); sp->storage_class = sc_auto; sp->SetType(tp); sp->IsPrototype = FALSE; currentFn->lsyms.insert(sp); return sp; }
SYM *makeint(char *name) { SYM *sp; TYP *tp; sp = allocSYM(); tp = allocTYP(); tp->type = bt_long; tp->size = 8; tp->btp = 0; tp->lst.head = 0; tp->sname = 0; sp->name = name; sp->storage_class = sc_auto; sp->tp = tp; sp->IsPrototype = FALSE; insert(sp,&lsyms); return sp; }
void ParseEnumDeclaration(TABLE *table) { SYM *sp; TYP *tp; if( lastst == id) { if((sp = search(lastid,&tagtable)) == NULL) { sp = allocSYM(); sp->tp = allocTYP(); sp->tp->type = bt_enum; sp->tp->size = 2; sp->tp->lst.head = 0; sp->tp->btp = 0; sp->storage_class = sc_type; sp->name = litlate(lastid); sp->tp->sname = sp->name; NextToken(); if( lastst != begin) error(ERR_INCOMPLETE); else { insert(sp,&tagtable); NextToken(); ParseEnumerationList(table); } } else NextToken(); head = sp->tp; } else { tp = allocTYP(); // fix here tp->type = bt_enum; tp->size = 2; if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseEnumerationList(table); } head = tp; } }
void ParseEnumDeclaration(TABLE *table) { SYM *sp; TYP *tp; if( lastst == id) { if((sp = search(lastid,&tagtable)) == NULL) { sp = allocSYM(); sp->tp = TYP::Make(bt_enum,1); sp->storage_class = sc_type; sp->SetName(*(new std::string(lastid))); sp->tp->sname = new std::string(*sp->name); NextToken(); if( lastst != begin) error(ERR_INCOMPLETE); else { tagtable.insert(sp); NextToken(); ParseEnumerationList(table); } } else NextToken(); head = sp->tp; } else { tp = allocTYP(); // fix here tp->type = bt_enum; tp->size = 1; if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseEnumerationList(table); } head = tp; } }
int ParseStructDeclaration(int ztype) { SYM *sp; TYP *tp; int gblflag; int ret; int psd; ENODE nd; ENODE *pnd = &nd; psd = isStructDecl; isStructDecl = TRUE; ret = 0; bit_offset = 0; bit_next = 0; bit_width = -1; if(lastst == id) { if((sp = search(lastid,&tagtable)) == NULL) { // If we encounted an unknown struct in a parameter list, we want // it to go into the global memory pool, not a local one. if (parsingParameterList) { gblflag = global_flag; global_flag++; sp = allocSYM(); sp->name = litlate(lastid); global_flag = gblflag; } else { sp = allocSYM(); sp->name = litlate(lastid); } sp->tp = allocTYP(); sp->tp->type = ztype; sp->tp->typeno = typeno++; sp->tp->lst.head = 0; sp->storage_class = sc_type; sp->tp->sname = sp->name; sp->tp->alignment = 0; NextToken(); if (lastst == kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } // Could be a forward structure declaration like: // struct buf; if (lastst==semicolon) { ret = 1; insert(sp,&tagtable); NextToken(); } // Defining a pointer to an unknown struct ? else if (lastst == star) { insert(sp,&tagtable); } else if(lastst != begin) error(ERR_INCOMPLETE); else { insert(sp,&tagtable); NextToken(); ParseStructMembers(sp->tp,ztype); } } else { NextToken(); if (lastst==kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } if (lastst==begin) { NextToken(); ParseStructMembers(sp->tp,ztype); } } head = sp->tp; } else { tp = allocTYP(); tp->type = ztype; tp->sname = 0; tp->lst.head = 0; if (lastst==kw_align) { NextToken(); tp->alignment = GetIntegerExpression(&pnd); } if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseStructMembers(tp,ztype); } head = tp; } isStructDecl = psd; return ret; }
void ClassDeclaration::ParseMembers(SYM *sym, int ztype) { int slc; TYP *tp = sym->tp; int ist; SYM *hsym; std::string *name; isPrivate = true; if (sym->tp->size) slc = roundSize(sym->tp); else slc = 0; // slc = 0; tp->val_flag = 1; // tp->val_flag = FALSE; ist = isTypedef; isTypedef = false; // First add a hidden member that indicates the class number. The type // number is used during virtual function calls to determine which // method to call. This is the first field in the class so it can be // refeerenced as 0[r25]. hsym = allocSYM(); name = new std::string("_typeno"); hsym->SetName(*name); hsym->storage_class = sc_member; hsym->value.i = sym->tp->typeno; hsym->tp = TYP::Make(bt_char,2); hsym->tp->sname = new std::string("_typeno"); hsym->tp->alignment = 2; tp->lst.insert(hsym); slc += 2; while( lastst != end) { if (lastst==kw_public) isPrivate = false; if (lastst==kw_private) isPrivate = true; if (lastst==kw_public || lastst==kw_private) { NextToken(); if (lastst==colon) NextToken(); } if (lastst==kw_unique || lastst==kw_static) { NextToken(); declare(sym,&(tp->lst),sc_static,slc,ztype); } else { if(ztype == bt_struct || ztype==bt_class) slc += declare(sym,&(tp->lst),sc_member,slc,ztype); else slc = imax(slc,declare(sym,&(tp->lst),sc_member,0,ztype)); } } bit_offset = 0; bit_next = 0; bit_width = -1; tp->size = tp->alignment ? tp->alignment : slc; NextToken(); isTypedef = ist; }
// Class declarations have the form: // // class identifier [: base class] // { // class members // } // // We could also have a forward reference: // // class identifier; // // Or a pointer to a class: // // class *identifier; // int ClassDeclaration::Parse(int ztype) { SYM *sp, *bcsp; int ret; int psd; ENODE nd; ENODE *pnd = &nd; char *idsave; int alignment; SYM *cls; cls = currentClass; dfs.puts("<ParseClassDeclaration>\n"); alignment = 0; isTypedef = TRUE; NextToken(); if (lastst != id) { error(ERR_SYNTAX); goto lxit; } // ws = allocSYM(); idsave = my_strdup(lastid); // ws->name = idsave; // ws->storage_class = sc_typedef; // Passes lastid onto struct parsing psd = isStructDecl; isStructDecl++; ret = 0; bit_offset = 0; bit_next = 0; bit_width = -1; dfs.printf("---------------------------------"); dfs.printf("Class decl:%s\n", lastid); dfs.printf("---------------------------------"); if((sp = tagtable.Find(std::string(lastid),false)) == NULL) { sp = allocSYM(); sp->SetName(*(new std::string(lastid))); sp->tp = nullptr; NextToken(); dfs.printf("A"); if (lastst == kw_align) { NextToken(); alignment = GetIntegerExpression(&pnd); } else alignment = AL_STRUCT; // Could be a forward structure declaration like: // struct buf; if (lastst==semicolon) { dfs.printf("B"); ret = 1; printf("classdecl insert1\r\n"); tagtable.insert(sp); NextToken(); } // Defining a pointer to an unknown struct ? else if (lastst == star) { dfs.printf("C"); printf("classdecl insert2\r\n"); tagtable.insert(sp); } else if (lastst==colon) { dfs.printf("D"); NextToken(); // Absorb and ignore public/private keywords if (lastst == kw_public || lastst==kw_private) NextToken(); if (lastst != id) { error(ERR_SYNTAX); goto lxit; } bcsp = tagtable.Find(std::string(lastid),false); if (bcsp==nullptr) { error(ERR_UNDEFINED); goto lxit; } dfs.printf("E"); // Copy the type chain of base class //sp->tp = TYP::Copy(bcsp->tp); // Start off at the size of the base. sp->tp = allocTYP(); sp->tp->lst.SetBase(bcsp->GetIndex()); dfs.printf("Set base class: %d\n", sp->tp->lst.base); sp->tp->size = bcsp->tp->size; sp->tp->type = (e_bt)ztype; sp->tp->typeno = typeno++; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = alignment; sp->storage_class = sc_type; NextToken(); if (lastst != begin) { error(ERR_INCOMPLETE); goto lxit; } /* sp->tp = allocTYP(); sp->tp->typeno = typeno++; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = alignment; sp->tp->type = (e_bt)ztype; sp->tp->lst.SetBase(bcsp->GetIndex()); sp->storage_class = sc_type; */ tagtable.insert(sp); NextToken(); currentClass = sp; dfs.printf("f"); ParseMembers(sp,ztype); dfs.printf("G"); } else if(lastst != begin) error(ERR_INCOMPLETE); else { if (sp->tp == nullptr) { sp->tp = allocTYP(); } sp->tp->size = 0; sp->tp->typeno = typeno++; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = alignment; sp->tp->type = (e_bt)ztype; sp->tp->lst.SetBase(0); sp->storage_class = sc_type; tagtable.insert(sp); NextToken(); currentClass = sp; ParseMembers(sp,ztype); } } // Else the class was found in the tag table. else { NextToken(); if (lastst==kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } if (lastst==begin) { NextToken(); currentClass = sp; ParseMembers(sp,ztype); } } head = sp->tp; isStructDecl = psd; lxit: isTypedef = TRUE; if (classname) delete classname; classname = new std::string(idsave); currentClass = cls; dfs.puts("</ParseClassDeclaration>\n"); return ret; }
int StructDeclaration::Parse(int ztype) { SYM *sp; TYP *tp; int ret; int psd; ENODE nd; ENODE *pnd = &nd; sp = nullptr; psd = isStructDecl; isStructDecl++; ret = 0; bit_offset = 0; bit_next = 0; bit_width = -1; if(lastst == id) { if((sp = tagtable.Find(lastid,false)) == NULL) { sp = allocSYM(); sp->SetName(*(new std::string(lastid))); sp->tp = allocTYP(); sp->tp->type = (e_bt)ztype; sp->tp->typeno = typeno++; sp->tp->lst.Clear(); sp->storage_class = sc_type; sp->tp->sname = new std::string(*sp->name); sp->tp->alignment = 0; NextToken(); if (lastst == kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } // Could be a forward structure declaration like: // struct buf; if (lastst==semicolon) { ret = 1; tagtable.insert(sp); NextToken(); } // Defining a pointer to an unknown struct ? else if (lastst == star) { tagtable.insert(sp); } else if(lastst != begin) error(ERR_INCOMPLETE); else { tagtable.insert(sp); NextToken(); ParseMembers(sp, sp->tp,ztype); } } // Else it is a known structure else { NextToken(); if (lastst==kw_align) { NextToken(); sp->tp->alignment = GetIntegerExpression(&pnd); } if (lastst==begin) { NextToken(); ParseMembers(sp,sp->tp,ztype); } } head = sp->tp; } // Else there was no tag identifier else { tp = allocTYP(); tp->type = (e_bt)ztype; tp->typeno = typeno++; tp->sname = new std::string(""); if (lastst==kw_align) { NextToken(); tp->alignment = GetIntegerExpression(&pnd); } if( lastst != begin) error(ERR_INCOMPLETE); else { NextToken(); ParseMembers(sp,tp,ztype); } head = tp; } isStructDecl = psd; return ret; }
/* * process declarations of the form: * * <type> <specifier>, <specifier>...; * * leaves the declarations in the symbol table pointed to by * table and returns the number of bytes declared. al is the * allocation type to assign, ilc is the initial location * counter. if al is sc_member then no initialization will * be processed. ztype should be bt_struct for normal and in * structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations. */ int declare(TABLE *table,int al,int ilc,int ztype) { SYM *sp, *sp1, *sp2; TYP *dhead, *tp1, *tp2; ENODE *ep1, *ep2; char stnm[200]; int op; int fd; int fn_doneinit = 0; int bcnt; static long old_nbytes; int nbytes; nbytes = 0; if (ParseSpecifier(table)) return nbytes; dhead = head; for(;;) { declid = (char *)NULL; bit_width = -1; ParseDeclarationPrefix(ztype==bt_union); // If a function declaration is taking place and just the type is // specified without a parameter name, assign an internal compiler // generated name. if (funcdecl>0 && funcdecl != 10 && declid==(char *)NULL) { sprintf(lastid, "_p%d", nparms); declid = litlate(lastid); names[nparms++] = declid; missingArgumentName = TRUE; } if( declid != NULL) { /* otherwise just struct tag... */ sp = allocSYM(); sp->name = declid; sp->storage_class = al; sp->isConst = isConst; if (bit_width > 0 && bit_offset > 0) { // share the storage word with the previously defined field nbytes = old_nbytes - ilc; } old_nbytes = ilc + nbytes; if (al != sc_member) { // sp->isTypedef = isTypedef; if (isTypedef) sp->storage_class = sc_typedef; isTypedef = FALSE; } if ((ilc + nbytes) % roundAlignment(head)) { if (al==sc_thread) tseg(); else dseg(); } bcnt = 0; while( (ilc + nbytes) % roundAlignment(head)) { ++nbytes; bcnt++; } if( al != sc_member && al != sc_external && al != sc_auto) { if (bcnt > 0) genstorage(bcnt); } // Set the struct member storage offset. if( al == sc_static || al==sc_thread) { sp->value.i = nextlabel++; } else if( ztype == bt_union) sp->value.i = ilc; else if( al != sc_auto ) sp->value.i = ilc + nbytes; // Auto variables are referenced negative to the base pointer // Structs need to be aligned on the boundary of the largest // struct element. If a struct is all chars this will be 2. // If a struct contains a pointer this will be 8. It has to // be the worst case alignment. else { sp->value.i = -(ilc + nbytes + roundSize(head)); } if (bit_width == -1) sp->tp = head; else { sp->tp = allocTYP(); *(sp->tp) = *head; sp->tp->type = bt_bitfield; sp->tp->size = head->size;//tp_int.size; sp->tp->bit_width = bit_width; sp->tp->bit_offset = bit_offset; } if (isConst) sp->tp->isConst = TRUE; if((sp->tp->type == bt_func) && sp->storage_class == sc_global ) sp->storage_class = sc_external; // Increase the storage allocation by the type size. if(ztype == bt_union) nbytes = imax(nbytes,roundSize(sp->tp)); else if(al != sc_external) { // If a pointer to a function is defined in a struct. if (isStructDecl && (sp->tp->type==bt_func || sp->tp->type==bt_ifunc)) nbytes += 8; else nbytes += roundSize(sp->tp); } if (sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 && sp1->tp->type == bt_func ) { sp1->tp = sp->tp; sp1->storage_class = sp->storage_class; sp1->value.i = sp->value.i; sp1->IsPrototype = sp->IsPrototype; sp = sp1; } else { sp2 = search(sp->name,table); if (sp2 == NULL) insert(sp,table); else { if (funcdecl==2) sp2->tp = sp->tp; //else if (!sp2->IsPrototype) // insert(sp,table); } } if (needParseFunction) { needParseFunction = FALSE; fn_doneinit = ParseFunction(sp); if (sp->tp->type != bt_pointer) return nbytes; } // if(sp->tp->type == bt_ifunc) { /* function body follows */ // ParseFunction(sp); // return nbytes; // } if( (al == sc_global || al == sc_static || al==sc_thread) && !fn_doneinit && sp->tp->type != bt_func && sp->tp->type != bt_ifunc && sp->storage_class!=sc_typedef) doinit(sp); } if (funcdecl>0) { if (lastst==comma || lastst==semicolon) break; if (lastst==closepa) goto xit1; } else if (catchdecl==TRUE) { if (lastst==closepa) goto xit1; } else if (lastst == semicolon) break; else if (lastst == assign) { tp1 = nameref(&ep1); op = en_assign; // NextToken(); tp2 = asnop(&ep2); if( tp2 == 0 || !IsLValue(ep1) ) error(ERR_LVALUE); else { tp1 = forcefit(&ep1,tp1,&ep2,tp2); ep1 = makenode(op,ep1,ep2); } sp->initexp = ep1; if (lastst==semicolon) break; } needpunc(comma); if(declbegin(lastst) == 0) break; head = dhead; } NextToken(); xit1: return nbytes; }
/* * process ParseSpecifierarations of the form: * * <type> <ParseSpecifier>, <ParseSpecifier>...; * * leaves the ParseSpecifierarations in the symbol table pointed to by * table and returns the number of bytes declared. al is the * allocation type to assign, ilc is the initial location * counter. if al is sc_member then no initialization will * be processed. ztype should be bt_struct for normal and in * structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations. */ int declare(TABLE *table,int al,int ilc,int ztype) { SYM *sp, *sp1, *sp2; TYP *dhead; char stnm[200]; static long old_nbytes; int nbytes; nbytes = 0; ParseSpecifier(table); dhead = head; for(;;) { declid = 0; bit_width = -1; ParseDeclarationPrefix(ztype==bt_union); if( declid != 0) { /* otherwise just struct tag... */ sp = allocSYM(); sp->name = declid; sp->storage_class = al; if (bit_width > 0 && bit_offset > 0) { // share the storage word with the previously defined field nbytes = old_nbytes - ilc; } old_nbytes = ilc + nbytes; if (al != sc_member) { // sp->isTypedef = isTypedef; if (isTypedef) sp->storage_class = sc_typedef; isTypedef = FALSE; } while( (ilc + nbytes) % alignment(head)) { if( al != sc_member && al != sc_external && al != sc_auto) { dseg(); GenerateByte(0); } ++nbytes; } if( al == sc_static) { sp->value.i = nextlabel++; } else if( ztype == bt_union) sp->value.i = ilc; else if( al != sc_auto ) sp->value.i = ilc + nbytes; else sp->value.i = -(ilc + nbytes + head->size); if (bit_width == -1) sp->tp = head; else { sp->tp = allocTYP(); *(sp->tp) = *head; sp->tp->type = bt_bitfield; sp->tp->size = head->size;//tp_int.size; sp->tp->bit_width = bit_width; sp->tp->bit_offset = bit_offset; } if( (sp->tp->type == bt_func) && sp->storage_class == sc_global ) sp->storage_class = sc_external; if(ztype == bt_union) nbytes = imax(nbytes,sp->tp->size); else if(al != sc_external) nbytes += sp->tp->size; if( sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 && sp1->tp->type == bt_func ) { sp1->tp = sp->tp; sp1->storage_class = sp->storage_class; // sp1->value.i = sp->value.i; sp1->IsPrototype = sp->IsPrototype; sp = sp1; } else { sp2 = search(sp->name,table); if (sp2 == NULL) insert(sp,table); else { if (funcdecl==2) sp2->tp = sp->tp; //else if (!sp2->IsPrototype) // insert(sp,table); } } if( sp->tp->type == bt_ifunc) { /* function body follows */ ParseFunction(sp); return nbytes; } if( (al == sc_global || al == sc_static) && sp->tp->type != bt_func && sp->storage_class!=sc_typedef) doinit(sp); } if (funcdecl==TRUE) { if (lastst==comma || lastst==semicolon) break; if (lastst==closepa) goto xit1; } else if (catchdecl==TRUE) { if (lastst==closepa) goto xit1; } else if (lastst == semicolon) break; needpunc(comma); if(declbegin(lastst) == 0) break; head = dhead; } NextToken(); xit1: return nbytes; }