⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileset.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
        error_line(1, NULL, "File '%s' has non-integer symtab pointer",                   is->name());    }    if (!position_immed.is_long_int()) {        error_line(1, NULL,                   "File '%s' is too big -- symtab pointer out of range of "                   "file indexing on this machine", is->name());    }    long pos = position_immed.long_int();    delete an;    delete mrk;    if (pos == -1) {        error_line(1, NULL,                   "File '%s' has no symtab pointer -- probably the result "                   "of a SUIF file which was never completely written out",                   is->name());    }    is->setpos(pos);    /* read the global symtab (temporarily make the new global symtab       a child of the existing one so that it can access the predefined       types while it is being read in) */    global_symtab *tmp_globals = new global_symtab("globals");    parent()->globals()->add_child(tmp_globals);    tmp_globals->read(is);    parent()->globals()->remove_child(tmp_globals);    if (parent()->read_a_file) {	/* make sure the new symbol table matches and delete it */	if (!disable_global_symtab_check)	    check_global_symtab(tmp_globals);	delete tmp_globals;    } else {	/* move the file_symtab to be a child of tmp_globals */	parent()->globs->remove_child(symtab());	tmp_globals->add_child(symtab());	/* make sure the existing symbol table is empty (except possibly for	   some predefined types) and replace it */	assert_msg(parent()->globs->symbols()->is_empty() &&		   parent()->globs->children()->is_empty(),		   ("global symbol table not empty"));	delete parent()->globs;	parent()->globs = tmp_globals;    }    /* read the file symtab */    symtab()->read(is);    /* no need to restore the stream position */}/* *  Make sure that a new global symtab matches the existing global symtab. *  (The files in a file_set must be "linked" together by a separate SUIF *  pass to match up the global symtab entries.) */voidfile_set_entry::check_global_symtab (global_symtab *newglobs){    global_symtab *globals = parent()->globals();    type_node_list_iter type_iter(newglobs->types());    while (!type_iter.is_empty()) {	type_node *newtyp = type_iter.step();	type_node *oldtyp = globals->lookup_type_id(newtyp->type_id());	/* make sure they're equivalent */	if (!oldtyp ||	    (oldtyp->op() != newtyp->op()) ||	    (oldtyp->size() != newtyp->size())) {	    error_line(-1, NULL, "type in global symbol table does not match");	}    }    sym_node_list_iter sym_iter(newglobs->symbols());    while (!sym_iter.is_empty()) {	sym_node *newsym = sym_iter.step();	sym_node *oldsym = globals->lookup_sym_id(newsym->sym_id());	/* make sure they're equivalent */	if (!oldsym ||	    (oldsym->kind() != newsym->kind()) ||	    (oldsym->name() != newsym->name())) {	    error_line(-1, NULL, "symbol in global symtab does not match");	}    }}/* *  Several kinds of information are included as annotations on the *  file_set_entries.  These annotations are stripped off when the file *  is first opened.  First, the target machine parameters are read.  If *  this is the first input file to be read, the global "target" structure *  is updated.  Otherwise, the parameters are checked against the existing *  ones.  Second, the file_set_entry contains annotations to identify *  procedure symbols whose bodies are defined within the file.  This *  information is read and used to set the "file" pointers in the proc_syms. */voidfile_set_entry::get_contents (){    /* read the target machine parameters */    get_machine_param((int*)&target.is_big_endian, k_is_big_endian,		      FALSE, parent()->read_a_file);    get_machine_param(&target.addressable_size, k_addressable_size,		      FALSE, parent()->read_a_file);    get_machine_param((int*)&target.char_is_signed, k_char_is_signed,		      FALSE, parent()->read_a_file);    while (get_machine_param(&target.size[0], k_C_type_size,			     TRUE, parent()->read_a_file)) {    }    while (get_machine_param(&target.align[0], k_C_type_align,			     TRUE, parent()->read_a_file)) {    }    get_machine_param(&target.array_align, k_array_align,		      FALSE, parent()->read_a_file);    get_machine_param(&target.struct_align, k_struct_align,		      FALSE, parent()->read_a_file);    int tmp_pdiff_type = target.ptr_diff_type;    get_machine_param(&tmp_pdiff_type, k_ptr_diff_type,		      FALSE, parent()->read_a_file);    target.ptr_diff_type = (C_types)tmp_pdiff_type;    /* check if this is the first input file */    if (!parent()->read_a_file) {	parent()->read_a_file = TRUE;	/* reset the predefined type pointers to use the new parameters */	parent()->globals()->predefine_types();    }    /* find out which procedure bodies are contained in this file */    immed_list *iml;    while ((iml = (immed_list *)get_annote(k_proc_in_file))) {	proc_sym *psym = (proc_sym *)iml->pop().symbol();	assert(psym->is_proc());	psym->set_extern(FALSE);	psym->fse = this;	psym->file_pos = iml->pop().long_int();	delete iml;    }}/* *  Read a machine parameter annotation from the file_set_entry.  If this *  is the first entry in the file_set, the parameter overrides the default *  value.  Otherwise, this just checks that all of the parameters match *  the values specified in the first file_set_entry. */booleanfile_set_entry::get_machine_param (int *flag, char *annote_name,				   boolean is_array, boolean read_a_file){    immed_list *iml = (immed_list *)get_annote(annote_name);    if (iml) {	int val = iml->pop().integer();	if (is_array) {	    flag += val;	    val = iml->pop().integer();	}	delete iml;	if (read_a_file) {	    if (*flag != val) {		error_line(1, NULL, "machine parameter annotation '%s' "			   "does not match", annote_name);	    }	} else {	    *flag = val;	}	return TRUE;    }    return FALSE;}/* *  Write out the global and file symbol tables. */voidfile_set_entry::write_table (){    /* get the file position where the symtab will be written */    long current_pos = os->getpos();    /* create a mark to record the symtab position */    instruction *symtab_ptr = new in_rrr(io_mrk);    annote *an = new annote(k_file_symtab_ptr);    an->immeds()->append(immed(current_pos));    symtab_ptr->annotes()->append(an);    /* write the mark at the beginning of the file */    os->flush_cache();    os->setpos(symtab_ptr_loc);    symtab_ptr->write(os);    delete symtab_ptr;    /* go back and write out the symtab */    os->setpos(current_pos);    os->flush_cache();    parent()->globals()->write(os);    symtab()->write(os);}/* *  File_set_entry destructor.  If necessary, write out the file_symtab *  and file_set_entry annotations.  Close the i/o streams. */file_set_entry::~file_set_entry (){    delete global_proc_iter;    delete static_proc_iter;    /* close the i/o streams */    if (is) {	parent()->close_stream(is);	delete is;    }    if (os) {	parent()->open_stream(os, this);        assert(write_scope == NULL);        write_scope = symtab();	/* write the file symtab */	write_table();	/* save the target machine parameters on the file_set_entry */	save_machine_param(target.is_big_endian, k_is_big_endian, -1);	save_machine_param(target.addressable_size, k_addressable_size, -1);	save_machine_param(target.char_is_signed, k_char_is_signed, -1);	for (int i = 0; i < num_C_types; i++) {	    save_machine_param(target.size[i], k_C_type_size, i);	    save_machine_param(target.align[i], k_C_type_align, i);	}	save_machine_param(target.array_align, k_array_align, -1);	save_machine_param(target.struct_align, k_struct_align, -1);	save_machine_param(target.ptr_diff_type, k_ptr_diff_type, -1);	if (file_id() != 0) {	    immed_list *file_num_immeds = new immed_list;	    file_num_immeds->append(immed(file_id()));	    append_annote(k_file_num, file_num_immeds);	}	/* write the file_set_entry annotations */	instruction *mrk = new in_rrr(io_mrk);	copy_annotes(mrk);	mrk->write(os);	delete mrk;	/* write the end-of-stream marker */	os->write_int((int)io_eos);        assert(write_scope == symtab());        write_scope = NULL;	parent()->close_stream(os);	delete os;    }    /* remove the symtab from its parent's child list */    if (symtab()) {	assert_msg(symtab()->parent(), ("symbol table has no parent!")); 	symtab()->parent()->remove_child(symtab()); 	delete symtab();    }}/* *  Save one of the target machine parameters as an annotation on the *  file_set_entry.  If the "ndx" parameter is non-negative, store it *  as the first immed value on the annotation. */voidfile_set_entry::save_machine_param (int val, char *annote_name, int ndx){    annote *an = new annote(annote_name);    if (ndx >= 0) {	an->immeds()->append(immed(ndx));    }    an->immeds()->append(immed(val));    annotes()->append(an);}/* *  Find the name of the file.  If there is no input stream, use the *  name from the output stream. */char *file_set_entry::name (){    if (is) return is->name();    return os->name();}voidfile_set_entry::add_outfile (char *outn){    assert(os == NULL);    assert(outn != NULL);    os = new out_stream(lexicon->enter(outn)->sp);    /* write the header for the output stream */    par->open_stream(os, this);    assert(write_scope == NULL);    write_scope = table;    /* write out a mark to record the position of the file symtab */    instruction *mrk = new in_rrr(io_mrk);    annote *an = new annote(k_file_symtab_ptr);    an->immeds()->append(immed(-1));    mrk->annotes()->append(an);    symtab_ptr_loc = os->getpos();    mrk->write(os);    delete mrk;    assert(write_scope == table);    write_scope = NULL;}/* *  Reset the procedure iterators. */voidfile_set_entry::reset_proc_iter (){    global_proc_iter->reset(parent()->globals()->symbols());    static_proc_iter->reset(symtab()->symbols());}/* *  Find the next proc_sym that is defined (not extern).  Because *  proc_syms may appear in either the global or file symtabs, we *  actually need two iterators here. */proc_sym *file_set_entry::next_proc (){    /* first check the file symtab */    while (!static_proc_iter->is_empty()) {	sym_node *sn = static_proc_iter->step();	if (sn->is_proc()) return (proc_sym *)sn;    }    /* next check the global symtab */    while (!global_proc_iter->is_empty()) {	sym_node *sn = global_proc_iter->step();	if (sn->is_proc()) {	    proc_sym *psym = (proc_sym *)sn;	    if (psym->file() == this) return psym;	}    }    return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -