📄 init.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
/*
* handles initialization of module-scoped declarations
*/
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <float.h>
#include <math.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "lists.h"
#include "diag.h"
extern int prm_c99;
extern int structlevel;
extern TYP *head, **headptr;
extern struct template *currentTemplate;
extern SNODE *funcstmt;
extern int stdaddrsize;
extern int stdldoublesize;
extern enum e_sym lastst;
extern char lastid[], laststr[];
extern int skm_declend[];
extern int nextlabel;
extern TYP stdmatch;
extern int skm_declclosepa[];
extern int skm_closebr[];
extern int prm_cplusplus, prm_debug;
extern SYM *currentfunc;
extern int prm_bss;
extern int laststrlen;
extern LIST *varlisthead, *varlisttail;
extern int stdmemberptrsize;
extern SYM *typequal;
extern int total_errors;
extern char *cpp_funcname_tab[];
extern int conscount;
extern TRYBLOCK *try_block_list;
extern LIST *localfuncs;
extern SYM *parm_namespaces[20][100];
extern int parm_ns_counts[20];
extern int parm_ns_level;
extern int parsing_params;
void insertSpace(SYM *sp, int *bytes);
int virtualdata;
static SYM *locsp;
static short curbitsize;
static short startbit, bits, curbitsize;
static LLONG_TYPE totbits;
extern int stdinttype, stdunstype, stdintsize, stdldoublesize, stdaddrsize;
extern int stdshortsize, stdlongsize, stdlonglongsize, stdfloatsize, stddoublesize, stdenumsize;
static int allocated;
static ENODE *cpprefhead, *cpprefrundown;
static ENODE **cppreftail;
static int baseoffs = 0;
int bssbytes, databytes, constbytes;
static struct decldata **sptr;
static int begin_nesting;
static struct declares
{
struct declares *link;
SYM *sp;
} *declarations, *decltail, *virtualdecl, *virtualdecltail;
static long gen(SYM *sp);
static long gen2(SYM *sp);
int skm_semicolon[] =
{
semicolon, comma, 0
};
void initini(void)
{
cpprefhead = 0;
cpprefrundown = 0;
declarations = decltail = 0;
virtualdecl = virtualdecltail = 0;
databytes = bssbytes = constbytes = 0;
}
//-------------------------------------------------------------------------
void initrundown(void)
/*
* Dump out C++ pointer and reference initializations functions
*
* also dump out local vars
*
*/
{
int first, lbl;
struct declares *q;
long nbytes, obytes, val, onbytes, constnbytes;
SNODE stmt;
if (cpprefhead && !total_errors)
{
lbl = nextlabel++;
varlisthead = varlisttail = 0;
currentfunc = makesym(sc_static);
currentfunc->tp = maketype(bt_func, 0);
currentfunc->tp->btp = maketype(bt_void, 0);
currentfunc->tp->lst.head = 0;
currentfunc->intflag = 0;
currentfunc->faultflag = 0;
currentfunc->name = "__CPP_INIT_FUNC__";
memset(&stmt, 0, sizeof(stmt));
stmt.stype = st_expr;
stmt.next = 0;
stmt.exp = cpprefhead;
conscount = 0;
try_block_list = 0;
cseg();
genfunc(&stmt);
#ifdef ICODE
rewrite_icode();
#else
flush_peep();
#endif
cppseg();
gensrref(currentfunc, 50);
// genlong(20) ;
currentfunc = 0;
cpprefhead = 0;
} if (cpprefrundown && !total_errors)
{
lbl = nextlabel++;
varlisthead = varlisttail = 0;
currentfunc = makesym(sc_static);
currentfunc->tp = maketype(bt_func, 0);
currentfunc->tp->btp = maketype(bt_void, 0);
currentfunc->tp->lst.head = 0;
currentfunc->intflag = 0;
currentfunc->faultflag = 0;
currentfunc->name = "__CPP_RUNDOWN_FUNC__";
memset(&stmt, 0, sizeof(stmt));
stmt.stype = st_expr;
stmt.next = 0;
stmt.exp = cpprefrundown;
conscount = 0;
try_block_list = 0;
cseg();
genfunc(&stmt);
#ifdef ICODE
rewrite_icode();
#else
flush_peep();
#endif
cpprdseg();
gensrref(currentfunc, 50);
// genlong(100) ;
currentfunc = 0;
cpprefrundown = 0;
}
q = virtualdecl;
first = TRUE;
while (q)
{
SYM *sp = q->sp;
SetExtFlag(sp, FALSE);
if (first)
{
nl();
}
dseg();
first = FALSE;
gen_virtual(sp, TRUE);
gen2(sp);
gen_endvirtual(sp);
// if (prm_debug && !sp->staticlabel)
// debug_outdata(sp,FALSE) ;
sp->offset = 0;
q = q->link;
}
q = declarations;
nbytes = 0;
constnbytes = 0;
first = TRUE;
while (q)
{
SYM *sp = q->sp;
if (first)
{
nl();
}
first = FALSE;
if (sp && (sp->tp->size || !sp->tp->val_flag) && (sp->init || !prm_bss) && !sp->absflag)
{
int align = alignment(sc_global, sp->tp);
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
xconstseg();
else
dseg();
SetExtFlag(sp, FALSE);
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
val = align - (constnbytes % align);
else
val = align - (nbytes % align);
if (val != align)
{
genstorage(val, 0);
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
constnbytes += val;
else
nbytes += val;
nl();
}
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
{
onbytes = constnbytes;
constnbytes += gen(sp);
}
else
{
onbytes = nbytes;
nbytes += gen(sp);
}
if (prm_debug && !sp->staticlabel)
debug_outdata(sp, FALSE);
if (sp->offset != onbytes)
{
char buf[256];
sprintf(buf, "initrundown: data position mismatch %s", sp->name)
;
; /* + obytes */
DIAG(buf);
}
sp->offset = onbytes;
}
if (sp && !sp->tp->size && sp->tp->val_flag) {
TYP *tp = sp->tp, *tp1 = tp ;
while (tp->val_flag && !tp->size && tp->type == bt_pointer)
tp = tp->btp ;
while (tp1 && tp1 != tp) {
tp1->size = tp->size ;
tp1 = tp1->btp;
}
if (sp->tp->size == 0 || !prm_c99)
gensymerror(ERR_ZEROSTORAGE, sp->name);
else {
int *bytes;
sp->indecltable = FALSE ;
insert_decl_sp(sp) ; // relink it
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
bytes = &constbytes;
else if ((sp->init || !prm_bss) && !sp->absflag)
bytes = &databytes;
else
if (!sp->init && !sp->absflag)
bytes = &bssbytes;
sp->offset = *bytes ;
insertSpace(sp, bytes);
q->sp = 0 ;
}
}
q = q->link;
}
first = TRUE;
if (prm_bss)
{
/* obytes = nbytes; */
nbytes = 0;
constnbytes = 0;
q = declarations;
while (q)
{
SYM *sp = q->sp;
if (first)
{
nl();
}
first = FALSE;
if (sp && (sp->tp->size || !sp->tp->val_flag) && !sp->init && !sp->absflag)
{
int align = alignment(sc_global, sp->tp);
SetExtFlag(sp, FALSE);
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
xconstseg();
else
bssseg();
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
val = align - (constnbytes % align);
else
val = align - (nbytes % align);
if (val != align)
{
genstorage(val, 1);
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
constnbytes += val;
else
nbytes += val;
nl();
}
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
{
onbytes = constnbytes;
constnbytes += gen(sp);
}
else
{
if (sp->offset != nbytes)
{
genstorage(sp->offset - nbytes);
nl();
nbytes = sp->offset;
}
onbytes = nbytes;
nbytes += gen(sp);
}
// printf("%p:%p:%s:%x:%x:%x\n",sp,sp->mainsym,sp->name,sp->offset,sp->mainsym->offset,onbytes) ;
if (prm_debug && !sp->staticlabel)
debug_outdata(sp, TRUE);
if (sp->offset != onbytes)
{
char buf[256];
sprintf(buf, "initrundown: bss position mismatch %s", sp
->name);
; /* + obytes */
DIAG(buf);
}
}
if (sp && !sp->tp->size && sp->tp->val_flag) {
TYP *tp = sp->tp, *tp1 = tp ;
while (tp->val_flag && !tp->size && tp->type == bt_pointer)
tp = tp->btp ;
while (tp1 && tp1 != tp) {
tp1->size = tp->size ;
tp1 = tp1->btp;
}
if (sp->tp->size == 0 || !prm_c99)
gensymerror(ERR_ZEROSTORAGE, sp->name);
else {
int *bytes;
sp->indecltable = FALSE ;
insert_decl_sp(sp) ; // relink it
if ((sp->tp->cflags &DF_CONST) && !(sp->tp->cflags &DF_VOL))
bytes = &constbytes;
else if ((sp->init || !prm_bss) && !sp->absflag)
bytes = &databytes;
else
if (!sp->init && !sp->absflag)
bytes = &bssbytes;
sp->offset = *bytes ;
insertSpace(sp, bytes);
q->sp = 0 ;
}
}
q = q->link;
}
}
}
//-------------------------------------------------------------------------
static long gen2(SYM *sp)
{
struct decldata *decldata = sp->init;
long nbytes = 0;
if (decldata)
{
while (decldata)
{
switch (decldata->mode)
{
case dd_bool:
genbool(decldata->val.i);
nbytes ++;
break;
case dd_byte:
genbyte(decldata->val.i);
nbytes++;
;
break;
case dd_word:
genword(decldata->val.i);
nbytes += stdshortsize;
break;
case dd_enum:
genenum(decldata->val.i);
nbytes += stdenumsize;
break;
case dd_int:
genint(decldata->val.i);
nbytes += stdintsize;
break;
case dd_long:
genlong(decldata->val.i);
nbytes += stdlongsize;
break;
case dd_longlong:
genlonglong(decldata->val.i);
nbytes += stdlonglongsize;
break;
case dd_float:
genfloat(decldata->val.f[0]);
nbytes += stdfloatsize;
break;
case dd_double:
gendouble(decldata->val.f[0]);
nbytes += stddoublesize;
break;
case dd_ldouble:
genlongdouble(decldata->val.f[0]);
nbytes += stdldoublesize;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -