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; }
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); }
EXPRESSION *anonymousVar(enum e_sc storage_class, TYPE *tp) { static int anonct = 1; char buf[256]; SYMBOL *rv = (SYMBOL *)Alloc(sizeof(SYMBOL)); // if ((storage_class == sc_localstatic || storage_class == sc_auto) && !theCurrentFunc) // { // storage_class = sc_static; // insertInitSym(rv); // } if (tp->size == 0 && isstructured(tp)) tp = basetype(tp)->sp->tp; rv->storage_class = storage_class; rv->tp = tp; rv->anonymous = TRUE; rv->allocate = !anonymousNotAlloc; rv->assigned = TRUE; rv->used = TRUE; if (theCurrentFunc) rv->value.i = theCurrentFunc->value.i; sprintf(buf,"$anontemp%d", anonct++); rv->name = litlate(buf); tp->size = basetype(tp)->size; if (theCurrentFunc && !inDefaultParam) InsertSymbol(rv, storage_class, FALSE, FALSE); SetLinkerNames(rv, lk_none); return varNode(storage_class == sc_auto || storage_class == sc_parameter ? en_auto : storage_class == sc_localstatic ? en_label : en_global, rv); }
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 *ParseAsmStatement() { static char buf[2001]; int nn; Statement *snp; snp = NewStatement(st_asm, FALSE); while( isspace(lastch) ) getch(); NextToken(); if (lastst != begin) error(ERR_PUNCT); nn = 0; do { getch(); if (lastch=='}') break; buf[nn++] = lastch; } while(lastch!=-1 && nn < 2000); if (nn >= 2000) error(ERR_ASMTOOLONG); buf[nn] = '\0'; snp->label = litlate(buf); return snp; }
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; }
SYMBOL *gen_mp_virtual_thunk(SYMBOL *vsp) { QUAD *oi = intermed_head, *ot = intermed_tail; LIST *v = mpthunklist; SYMBOL *sp; IMODE *ap1, *ap2; char buf[256]; while (v) { sp = (SYMBOL*)v->data; if (sp->value.i == vsp->value.classdata.vtabindex) if (isstructured(vsp->tp->btp) == isstructured(sp->tp->btp)) return sp; v = v->link; } intermed_head = intermed_tail = NULL; blockMax = 0; blockCount = tempCount = 0; exitBlock = 0; IncGlobalFlag(); sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_static; sp->tp = vsp->tp; sp->value.i = vsp->value.classdata.vtabindex; //sprintf(buf, "@$mpt$%d$%d", sp->value.i, isstructured(sp->tp->btp)); sp->name = sp->decoratedName = litlate(buf); sp->errname = sp->decoratedName; sp->staticlabel = FALSE; sp->gennedvirtfunc = TRUE; v = (LIST *)Alloc(sizeof(LIST)); v->data = sp; v->link = mpthunklist; mpthunklist = v; DecGlobalFlag(); gen_virtual(sp, FALSE); addblock(i_goto); gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL); gen_icode(i_add, ap2, ap2 , make_immed(ISZ_NONE, isstructured(sp->tp->btp) ? ISZ_ADDR * 2 : ISZ_ADDR)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0); if (sp->value.classdata.baseofs) gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.classdata.baseofs)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0); gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.i)); ap1 = indnode(ap2, ISZ_ADDR); gen_icode(i_directbranch, 0, ap1, 0); addblock(i_ret); optimize(); rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(intermed_head); gen_endvirtual(sp); intermed_head = oi; intermed_tail = ot; return sp; }
void ParseDeclarationPrefix(char isUnion) { TYP *temp1, *temp2, *temp3, *temp4; switch (lastst) { case id: declid = litlate(lastid); if (funcdecl==1) names[nparms++] = declid; NextToken(); if (lastst == colon) { NextToken(); bit_width = GetIntegerExpression(); if (isUnion) bit_offset = 0; else bit_offset = bit_next; if (bit_width < 0 || bit_width > bit_max) { error(ERR_BITFIELD_WIDTH); bit_width = 1; } if (bit_width == 0 || bit_offset + bit_width > bit_max) bit_offset = 0; bit_next = bit_offset + bit_width; break; // no ParseDeclarationSuffix() } ParseDeclarationSuffix(); break; case star: temp1 = maketype(bt_pointer,8); temp1->btp = head; head = temp1; if(tail == NULL) tail = head; NextToken(); ParseDeclarationPrefix(isUnion); break; case openpa: NextToken(); temp1 = head; temp2 = tail; head = tail = NULL; ParseDeclarationPrefix(isUnion); needpunc(closepa); temp3 = head; temp4 = tail; head = temp1; tail = temp2; ParseDeclarationSuffix(); temp4->btp = head; if(temp4->type == bt_pointer && temp4->val_flag != 0 && head != NULL) temp4->size *= head->size; head = temp3; break; default: ParseDeclarationSuffix(); break; } }
/* Wrapper for function name mangling */ char * cppmangle(char *name, TYP *tp) { char buf[100]; if (*name == 0) return 0; if (prm_cmangle) name++; sprintf(buf,"@%s$",name); cppargs(buf+strlen(buf),tp->lst.head); return(litlate(buf)); }
EXPRESSION *tempenode(void) { SYMBOL *sp; char buf[256]; sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_temp; sprintf(buf, "$$t%d", tempCount); sp->name = litlate(buf); sp->value.i = tempCount++; return varNode(en_tempref, sp); }
/* * make s a string literal and return it's label number. */ int stringlit(char *s) { struct slit *lp; ++global_flag; /* always allocate from global space. */ lp = (struct slit *)xalloc(sizeof(struct slit)); lp->label = nextlabel++; lp->str = litlate(s); lp->next = strtab; strtab = lp; --global_flag; return lp->label; }
SYMBOL *getvc1Thunk(int offset) { char name[256]; SYMBOL *rv; sprintf(name, "@$vc1$B0$%d$0", offset+1); rv = search(name, vc1Thunks); if (!rv) { rv = Alloc(sizeof(SYMBOL)); rv->name = rv->errname = rv->decoratedName = litlate(name); rv->offset = offset; insert(rv, vc1Thunks); } return rv; }
int ccWriteFileName( char *name, sqlite_int64 *id) { char buf[260], *p = buf; HASHREC **q; while (*name) *p++ = tolower(*name++); *p = 0; q = LookupName(buf, listf); if (q) { *id = ((SYMID *)((*q)->p))->id; return TRUE; } name = litlate(buf); return ccWriteNameInTable(&whndlf, &shndlf, name, "FileNames", id, listf) == SQLITE_OK; }
static int lookuptype(char *buf) { int n = typehash(buf); struct _type_hash *t = typeHashTab[n]; while (t) { if (!strcmp(t->name, buf)) return t->id; t = t->next; } t = Alloc(sizeof(struct _type_hash)); t->id = typeIndex++; t->name = litlate(buf); t->next = typeHashTab[n]; typeHashTab[n] = t; return -t->id; }
int stringlit(char *s, int uselong) /* * make s a string literal and return it's label number. */ { struct slit *lp; ++global_flag; /* always allocate from global space. */ lp = xalloc(sizeof(struct slit)); lp->label = nextlabel++; if (uselong) lp->str = plitlate(s); else lp->str = litlate(s); lp->next = strtab; lp->type = uselong; strtab = lp; --global_flag; return lp->label; }
SYMBOL *gen_vsn_virtual_thunk(SYMBOL *func, int ofs) { QUAD *oi = intermed_head, *ot = intermed_tail; SYMBOL *sp; IMODE *ap1, *ap2; char buf[256]; //sprintf(buf, "@$vsn%s$%d", func->decoratedName, ofs); sp = search(buf, gsyms); if (sp) return sp; intermed_head = intermed_tail = NULL; blockMax = 0; blockCount = tempCount = 0; exitBlock = 0; IncGlobalFlag(); sp = Alloc(sizeof(SYMBOL)); sp->storage_class = sc_static; sp->value.i = ofs; sp->name = sp->decoratedName = litlate(buf); sp->errname = sp->decoratedName; sp->staticlabel = FALSE; sp->tp = func->tp; sp->gennedvirtfunc = TRUE; insert(sp, gsyms); DecGlobalFlag(); gen_virtual(sp, FALSE); addblock(i_goto); gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL ); gen_icode(i_add, ap1 = tempreg(ISZ_ADDR, 0), ap2, make_immed(ISZ_NONE, getSize(bt_pointer))); ap1 = indnode(ap1, ISZ_ADDR); gen_icode(i_add, ap1, ap1 , make_immed(ISZ_NONE, - ofs)); ap1 = make_imaddress(varNode(en_napccon, func), ISZ_ADDR); gen_icode(i_directbranch, 0, ap1, 0); addblock(i_ret); optimize(); rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(intermed_head); gen_endvirtual(sp); intermed_head = oi; intermed_tail = ot; return sp; }
IMODE *set_symbol(char *name, int isproc) /* * generate a call to a library routine. */ { SYMBOL *sp; IMODE *result; (void) isproc; sp = gsearch(name); if (sp == 0) { LIST *l1; IncGlobalFlag(); sp = (SYMBOL *)Alloc(sizeof(SYMBOL)); sp->storage_class = sc_external; sp->name = sp->errname = sp->decoratedName = litlate(name); sp->genreffed = TRUE; sp->tp = (TYPE *)Alloc(sizeof(TYPE)); sp->tp->type = isproc ? bt_func : bt_int; sp->safefunc = TRUE; insert(sp, globalNameSpace->syms); InsertExtern(sp); DecGlobalFlag(); } else { if (sp->storage_class == sc_overloads) sp = (SYMBOL *)(sp->tp->syms->table[0]->p); } result = (IMODE *)Alloc(sizeof(IMODE)); result->offset = varNode(en_global, sp); result->mode = i_direct; if (isproc) { result->offset->type = en_pc; if (chosenAssembler->arch->libsasimports) result->mode = i_direct; else result->mode = i_immed; } return result; }
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; } }
static int ccWriteMap( sqlite_int64 smpl_id, sqlite_int64 cplx_id, sqlite_int64 main_id) { char id[256]; static char *query = "INSERT INTO CPPNameMapping (simpleId, complexId, mainid) VALUES (?, ?, ?)"; int rc = SQLITE_OK; static sqlite3_stmt *handle, *handle1; if (!handle) rc = sqlite3_prepare_v2(dbPointer, query, strlen(query)+1, &handle, NULL); sprintf(id, "%d,%d", (int)smpl_id, (int)cplx_id); if (!LookupName(id, map)) { int done = FALSE; SYMID *v = (SYMID *)Alloc(sizeof(SYMID)); v->name = litlate(id); AddName((SYMBOL *)v, map); rc = SQLITE_DONE; sqlite3_reset(handle); sqlite3_bind_int64(handle, 1, smpl_id); sqlite3_bind_int64(handle, 2, cplx_id); sqlite3_bind_int64(handle, 3, main_id); while (!done) { switch(rc = sqlite3_step(handle)) { case SQLITE_BUSY: done = TRUE; break; case SQLITE_DONE: done = TRUE; rc = SQLITE_OK; break; default: done = TRUE; break; } } } return rc; }
SNODE *labelstmt(int fetchnext) /* * labelstmt processes a label that appears before a * statement as a seperate statement. */ { SNODE *snp; SYM *sp; snp = xalloc(sizeof(SNODE)); snp->next = 0; snp->stype = st_label; goodcode &= ~GF_UNREACH; if( (sp = search(lastid,&lsyms)) == 0 ) { sp = xalloc(sizeof(SYM)); sp->name = litlate(lastid); sp->storage_class = sc_label; sp->tp = xalloc(sizeof(TYP)); sp->tp->type = bt_unsigned; sp->tp->uflags = 0; sp->value.i = nextlabel++; insert(sp,&lsyms); } else { if( sp->storage_class != sc_ulabel ) gensymerror(ERR_DUPLABEL,sp->name); else sp->storage_class = sc_label; } getsym(); /* get past id */ needpunc(colon,0); if( sp->storage_class == sc_label ) { snp->label = (SNODE *)sp->value.i; snp->next = 0; if (lastst != end && fetchnext) snp->next = statement(); return snp; } return 0; }
SNODE *gotostmt(void) /* * gotostmt processes the goto statement and puts undefined * labels into the symbol table. */ { SNODE *snp; SYM *sp; getsym(); if( lastst != id ) { generror(ERR_IDEXPECT,0,0); return 0; } snp = xalloc(sizeof(SNODE)); snp->next = 0; if( (sp = search(lastid,&lsyms)) == 0 ) { sp = xalloc(sizeof(SYM)); sp->name = litlate(lastid); sp->value.i = nextlabel++; sp->storage_class = sc_ulabel; sp->tp = xalloc(sizeof(TYP)); sp->tp->type = bt_unsigned; insert(sp,&lsyms); } sp->tp->uflags = UF_USED; getsym(); /* get past label name */ if( lastst != eof) needpunc( semicolon,0 ); if( sp->storage_class != sc_label && sp->storage_class != sc_ulabel) gensymerror( ERR_LABEL,sp->name); else { snp->stype = st_goto; snp->label = (SNODE *)sp->value.i; snp->next = 0; return snp; } return 0; }
void ccLoadIdsFromNameTable(char *tabname, HASHTABLE *table) { static char *query = "SELECT name, id FROM %s"; int rc = SQLITE_OK; char qbuf[256]; SYMID *v; sqlite3_stmt *handle; sprintf(qbuf, query, tabname); rc = sqlite3_prepare_v2(dbPointer, qbuf, strlen(qbuf)+1, &handle, NULL); if (rc == SQLITE_OK) { BOOLEAN done = FALSE; while (!done) { switch(rc = sqlite3_step(handle)) { case SQLITE_BUSY: done = TRUE; break; case SQLITE_DONE: done = TRUE; break; case SQLITE_ROW: v = (SYMID *)Alloc(sizeof(SYMID)); v->name = litlate((char *)sqlite3_column_text(handle, 0)); v->id = sqlite3_column_int64(handle, 1); AddName((SYMBOL *)v, table); rc = SQLITE_OK; break; default: done = TRUE; break; } } sqlite3_finalize(handle); } }
/* Insert an overloaded function ref into the function table */ void funcrefinsert(char *name, char *mangname, TYP *tp, TABLE *tbl) { #ifdef CPLUSPLUS char buf[100]; SYM *sp,*sp1; sp = xalloc(sizeof(SYM)); buf[0] = '$'; buf[1] = '$'; strcpy(&buf[2],name); sp->defalt = mangname; sp->storage_class = sc_defunc; sp->value.overlist.head = 0; sp->name = litlate(buf); sp->tp = tp; sp1 = search(buf,tbl); if (sp1) if (sp1->value.overlist.head == 0) sp1->value.overlist.head = sp1->value.overlist.tail = sp; else sp1->value.overlist.tail = sp1->value.overlist.tail->next = sp; else insert(sp,tbl); #endif }
static char *LambdaName(void) { char buf[256]; if (lambdaIndex == 1) { char *p = strrchr(infile, '\\'); if (!p) { p = strrchr(infile, '/'); if (!p) p = infile; else p++; } else p++; sprintf(lambdaQualifier, "__%s__%d", p, rand()*RAND_MAX + rand()); while ((p = strchr(lambdaQualifier, '.')) != 0) *p = '_'; } sprintf(buf,"$$LambdaClosure%d%s", lambdaIndex++, lambdaQualifier); return litlate(buf); }
int ParseDeclarationPrefix(char isUnion) { TYP *temp1, *temp2, *temp3, *temp4; SYM *sp; int nn; char buf[200]; j2: switch (lastst) { case kw_const: isConst = TRUE; NextToken(); goto j2; case ellipsis: case id: j1: declid = litlate(lastid); if (funcdecl==1) names[nparms++] = declid; NextToken(); if (lastst == colon) { NextToken(); bit_width = GetIntegerExpression((ENODE **)NULL); if (isUnion) bit_offset = 0; else bit_offset = bit_next; if (bit_width < 0 || bit_width > bit_max) { error(ERR_BITFIELD_WIDTH); bit_width = 1; } if (bit_width == 0 || bit_offset + bit_width > bit_max) bit_offset = 0; bit_next = bit_offset + bit_width; break; // no ParseDeclarationSuffix() } //if (lastst==closepa) { // return 1; //} // if (lastst==closepa) { // sp = search(lastid,&gsyms[0]); // if (strcmp(lastid,"getchar")==0) // printf("found"); // if (sp) { // if (sp->storage_class==sc_typedef) // head = tail = sp->tp; // else // head = tail = sp->tp; //// head = tail = maketype(bt_long,4); // } // else { // head = tail = maketype(bt_long,8); // bit_max = 64; // } // break; // } ParseDeclarationSuffix(); break; case star: temp1 = maketype(bt_pointer,8); temp1->btp = head; head = temp1; if(tail == NULL) tail = head; NextToken(); //if (lastst==closepa) { // (*) // sprintf(buf,"_unnamed%d", unnamedCnt); // unnamedCnt++; // declid = litlate(buf); // NextToken(); // ParseDeclarationSuffix(); // return 2; //} // Loop back to process additional prefix info. goto j2; //return ParseDeclarationPrefix(isUnion); break; case openpa: NextToken(); temp1 = head; temp2 = tail; head = tail = (TYP *)NULL; // It might be a typecast following. // Do we have (getchar)() nn = ParseDeclarationPrefix(isUnion); /*if (nn==1) { head = temp1; tail = temp2; goto j1; }*/ //else if (nn == 2) { // head = temp1; // tail = temp2; // NextToken(); // ParseDeclarationSuffix(); // break; //} needpunc(closepa); temp3 = head; temp4 = tail; head = temp1; tail = temp2; ParseDeclarationSuffix(); // (getchar)() returns temp4 = NULL if (temp4!=NULL) { temp4->btp = head; if(temp4->type == bt_pointer && temp4->val_flag != 0 && head != NULL) temp4->size *= head->size; head = temp3; } //if (head==NULL) // head = tail = maketype(bt_long,8); break; default: ParseDeclarationSuffix(); break; } return 0; }
// Parse a specifier. This is the first part of a declaration. // Returns: // 0 usually, 1 if only a specifier is present // int ParseSpecifier(TABLE *table) { SYM *sp; isUnsigned = FALSE; isSigned = FALSE; isVolatile = FALSE; isConst = FALSE; for (;;) { switch (lastst) { case kw_const: // Ignore 'const' isConst = TRUE; NextToken(); break; case kw_typedef: isTypedef = TRUE; NextToken(); break; case kw_nocall: case kw_naked: isNocall = TRUE; head = tail = maketype(bt_oscall,8); NextToken(); break; case kw_oscall: isOscall = TRUE; head = tail = maketype(bt_oscall,8); NextToken(); goto lxit; case kw_interrupt: isInterrupt = TRUE; head = tail = maketype(bt_interrupt,8); NextToken(); if (lastst==openpa) { NextToken(); if (lastst!=id) error(ERR_IDEXPECT); needpunc(closepa); stkname = litlate(lastid); } goto lxit; case kw_pascal: isPascal = TRUE; head = tail = maketype(bt_pascal,8); NextToken(); break; // byte and char default to unsigned unless overridden using // the 'signed' keyword // case kw_byte: if (isUnsigned) head = tail = maketype(bt_ubyte,1); else head = tail = maketype(bt_byte,1); NextToken(); head->isUnsigned = !isSigned; head->isVolatile = isVolatile; head->isConst = isConst; bit_max = 8; goto lxit; case kw_char: if (isUnsigned) head = tail = maketype(bt_uchar,2); else head = tail = maketype(bt_char,2); NextToken(); head->isUnsigned = !isSigned; head->isVolatile = isVolatile; head->isConst = isConst; bit_max = 16; goto lxit; case kw_int16: if (isUnsigned) head = tail = maketype(bt_uchar,2); else head = tail = maketype(bt_char,2); NextToken(); head->isUnsigned = isUnsigned; head->isVolatile = isVolatile; head->isConst = isConst; bit_max = 16; goto lxit; case kw_int32: case kw_short: if (isUnsigned) head = tail = maketype(bt_ushort,4); else head = tail = maketype(bt_short,4); bit_max = 32; NextToken(); if( lastst == kw_int ) NextToken(); head->isUnsigned = isUnsigned; head->isVolatile = isVolatile; head->isConst = isConst; head->isShort = TRUE; goto lxit; break; case kw_long: // long, long int NextToken(); if (lastst==kw_int) { NextToken(); } else if (lastst==kw_float) { head = tail = maketype(bt_double,8); NextToken(); } else { if (isUnsigned) head = tail = maketype(bt_ulong,8); else head = tail = maketype(bt_long,8); } //NextToken(); if (lastst==kw_task) { isTask = TRUE; NextToken(); } if (lastst==kw_oscall) { isOscall = TRUE; NextToken(); } else if (lastst==kw_nocall || lastst==kw_naked) { isNocall = TRUE; NextToken(); } head->isUnsigned = isUnsigned; head->isVolatile = isVolatile; head->isConst = isConst; bit_max = 64; goto lxit; break; case kw_int64: case kw_int: if (isUnsigned) head = tail = maketype(bt_ulong,8); else head = tail = maketype(bt_long,8); head->isUnsigned = isUnsigned; head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); if (lastst==kw_task) { isTask = TRUE; NextToken(); } if (lastst==kw_oscall) { isOscall = TRUE; NextToken(); } else if (lastst==kw_nocall || lastst==kw_naked) { isNocall = TRUE; NextToken(); } bit_max = 64; goto lxit; break; case kw_task: isTask = TRUE; NextToken(); break; case kw_int8: if (isUnsigned) head = tail = maketype(bt_ubyte,1); else head = tail = maketype(bt_byte,1); head->isUnsigned = isUnsigned; head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); if (lastst==kw_oscall) { isOscall = TRUE; NextToken(); } if (lastst==kw_nocall || lastst==kw_naked) { isNocall = TRUE; NextToken(); } bit_max = 8; goto lxit; break; case kw_signed: isSigned = TRUE; NextToken(); break; case kw_unsigned: NextToken(); isUnsigned = TRUE; break; case kw_volatile: NextToken(); isVolatile = TRUE; break; case ellipsis: case id: /* no type ParseSpecifierarator */ sp = search(lastid,&gsyms[0]); if (sp) { if (sp->storage_class==sc_typedef) { NextToken(); head = tail = sp->tp; } else head = tail = sp->tp; // head = tail = maketype(bt_long,4); } else { head = tail = maketype(bt_long,8); bit_max = 64; } goto lxit; break; case kw_float: head = tail = maketype(bt_float,4); head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); bit_max = 32; goto lxit; case kw_double: head = tail = maketype(bt_double,8); head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); bit_max = 64; goto lxit; case kw_triple: head = tail = maketype(bt_triple,12); head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); bit_max = 96; goto lxit; case kw_void: head = tail = maketype(bt_void,0); head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); if (lastst==kw_interrupt) { isInterrupt = TRUE; NextToken(); } if (lastst==kw_nocall || lastst==kw_naked) { isNocall = TRUE; NextToken(); } bit_max = 0; goto lxit; case kw_enum: NextToken(); ParseEnumDeclaration(table); bit_max = 16; goto lxit; case kw_struct: NextToken(); if (ParseStructDeclaration(bt_struct)) return 1; goto lxit; case kw_union: NextToken(); if (ParseStructDeclaration(bt_union)) return 1; goto lxit; case kw_exception: head = tail = maketype(bt_exception,8); head->isVolatile = isVolatile; head->isConst = isConst; NextToken(); bit_max = 64; goto lxit; case kw_inline: NextToken(); break; default: goto lxit; } } lxit:; return 0; }
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 ccinit(int argc, char *argv[]) { char buffer[260]; char *p; int rv; int i; strcpy(copyright, COPYRIGHT); strcpy(version, STRING_VERSION); outfile[0] = 1; for (i = 1; i < argc; i++) if (argv[i][0] == '-' || argv[i][0] == '/') if (argv[i][1] == '!') { showBanner = FALSE; } if (showBanner) { #ifdef CPREPROCESSOR banner("CPP Version %s %s", version, copyright); #else banner("%s Version %s %s", chosenAssembler->progname, version, copyright); #endif } /* parse the environment and command line */ #ifndef CPREPROCESSOR if (chosenAssembler->envname && !parseenv(chosenAssembler->envname)) usage(argv[0]); #endif #ifdef MICROSOFT GetModuleFileNameA(NULL, buffer, sizeof(buffer)); #else strcpy(buffer, argv[0]); #endif parseconfigfile(buffer); if (!parse_args(&argc, argv, TRUE) || (!clist && argc == 1)) usage(argv[0]); /* tack the environment includes in */ addinclude(); /* Scan the command line for file names or response files */ { int i; for (i = 1; i < argc; i++) if (argv[i][0] == '@') parsefile(0, argv[i] + 1); else InsertAnyFile(argv[i], 0, - 1); } #ifndef PARSER_ONLY if ((clist && clist->next) && has_output_file) fatal("Cannot specify output file for multiple input files\n"); if (has_output_file && !cparams.prm_compileonly) { #ifndef CPREPROCESSOR if (chosenAssembler->insert_output_file) chosenAssembler->insert_output_file(outfile); #endif has_output_file = FALSE; } #else { LIST *t = clist; while (t) { t->data = litlate(fullqualify(t->data)); t = t->next; } } #endif /* Set up a ctrl-C handler so we can exit the prog */ signal(SIGINT, ctrlchandler); if (setjmp(ctrlcreturn)) exit(1); }
/* * 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; }