void MultiDimArrayDismantlerPass::do_file_set_block( FileSetBlock* file_set_block ) { SuifEnv *env = get_suif_env(); TypeBuilder *type_builder = (TypeBuilder *) env->get_object_factory(TypeBuilder::get_class_name()); suif_hash_map<MultiDimArrayType *,Type *> type_map; ReplacingWalker walker(env); list<MultiDimArrayType *> type_list; for (Iter<MultiDimArrayType> titer = object_iterator<MultiDimArrayType>(file_set_block); titer.is_valid(); titer.next()) { MultiDimArrayType *type = &titer.current(); type_list.push_back(type); } for (list<MultiDimArrayType *>::iterator tliter = type_list.begin();tliter != type_list.end();tliter ++) { MultiDimArrayType *type = *tliter; Type *rep_type = disassemble_multi_array_type(env,type_builder,type); type_map.enter_value(type,rep_type); to<BasicSymbolTable>(type->get_parent())->remove_symbol_table_object(type); walker.add_replacement(type,rep_type); } for (Iter<MultiDimArrayExpression> iter = object_iterator<MultiDimArrayExpression>(file_set_block); iter.is_valid(); iter.next()) { MultiDimArrayExpression *expr = &iter.current(); dismantle_multi_dim_array_expression(env,expr,type_builder,type_map); } file_set_block->walk(walker); };
ObjectLocation LocationModule::get_object_location(SuifObject *obj) { ObjectLocation loc; if (!obj) { return(loc); } // part of a stmt list: walk from the beginning of the list // down until we find a line # const SuifObject* child = NULL; const SuifObject* parent = obj; for (; parent != NULL; child = parent, parent = parent->get_parent()) { loc = read_line_number(obj); if (loc.get_is_known()) return(loc); if(is_kind_of<StatementList>(parent)){ StatementList* the_list = to<StatementList>(parent); for(Iter<Statement*> iter = the_list->get_statement_iterator(); iter.is_valid() && iter.current() != child; iter.next()) { loc = read_line_number(iter.current()); // for the original object, if it is a StatementList // return the first mark found in it. if (child == NULL && loc.get_is_known()) return(loc); } } if (loc.get_is_known()) return loc; } // Now try to just get the input file return(get_object_filename(obj)); // return(loc); };
/* Useful for printing annotations as comments. Expects that * the annotation is a BrickAnnote. */ void Printer::print_annote(Annote *annote) { start_comment(); IdString name = annote->get_name(); if (name != k_comment) fprintf(out, "[%s", name.chars()); if (is_kind_of<BrickAnnote>(annote)) { BrickAnnote *an = (BrickAnnote *)(annote); char *separator = ": "; for (Iter<SuifBrick*> iter = an->get_brick_iterator(); iter.is_valid(); iter.next()) { fputs(separator, out); separator = ", "; SuifBrick *brick = iter.current(); if (is_a<IntegerBrick>(brick)) { Integer i = ((IntegerBrick*)iter.current())->get_value(); if (i.is_c_string_int()) fputs(i.chars(), out); else fprintf(out, "%ld", i.c_long()); } else if (is_a<StringBrick>(brick)) { putc('"', out); for (const char *p = ((StringBrick*)iter.current())->get_value().c_str(); *p != '\0'; ++p) { if (*p == '"' || *p == '\\') putc('\\', out); putc(*p, out); } putc('"', out); } else { claim(is_a<SuifObjectBrick>(brick)); SuifObject *so = ((SuifObjectBrick*)brick)->get_object(); if (is_kind_of<Type>(so)) fprint(out, (TypeId)so); else { const char *kind = so ? get_class_name(so) : "NULL"; fprintf(out, "<<<%s object>>>", kind); } } } } else { claim(is_kind_of<GeneralAnnote>(annote), "Unexpected kind of Annote"); } if (name != k_comment) fputs("]", out); fputs("\n", out); }
/** find the field with the name. */ static FieldSymbol* find_field(GroupType* gtype, LString field_name) { for (Iter<SymbolTableObject*> iter = gtype->get_group_symbol_table()->get_symbol_table_object_iterator(); iter.is_valid(); iter.next()) { if (iter.current()->get_name() != field_name) continue; return to<FieldSymbol>(iter.current()); } return 0; }
void ConstantArrayPropagationPass::CollectInitializations() { if (!initializations.empty()) { initializations.clear() ; } DefinitionBlock* procDefBlock = procDef->get_definition_block() ; assert(procDefBlock != NULL) ; Iter<VariableDefinition*> varDefIter = procDefBlock->get_variable_definition_iterator() ; while (varDefIter.is_valid()) { VariableDefinition* varDef = varDefIter.current() ; assert(varDef != NULL) ; VariableSymbol* varSym = varDef->get_variable_symbol() ; ValueBlock* valBlock = varDef->get_initialization() ; assert(varSym != NULL) ; assert(valBlock != NULL) ; if (ValidSymbol(varSym)) { initializations[varSym] = valBlock ; varSym->append_annote(create_brick_annote(theEnv, "ConstPropArray")) ; } varDefIter.next() ; } }
Statement* multi_way_branch_statement_walker::dismantle_multi_way_branch_statement(MultiWayBranchStatement *the_case){ StatementList *replacement = create_statement_list(the_case->get_suif_env()); Expression *operand = the_case->get_decision_operand (); remove_suif_object(operand); DataType *type = operand->get_result_type(); CodeLabelSymbol *default_lab = the_case->get_default_target(); the_case->set_default_target(0); Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); IInteger value = pair.first; CodeLabelSymbol *lab = pair.second; IntConstant *exp = create_int_constant(the_case->get_suif_env(),type, value); // Expression *exp = create_load_constant_expression(get_env(),type,iconst); TypeBuilder *type_builder = (TypeBuilder *) the_case->get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); Expression *compare = create_binary_expression(the_case->get_suif_env(),type_builder->get_boolean_type(), k_is_equal_to, deep_suif_clone(operand), exp); replacement->append_statement(create_branch_statement(the_case->get_suif_env(),compare,lab)); iter.next(); } delete operand; replacement->append_statement(create_jump_statement(the_case->get_suif_env(),default_lab)); the_case->get_parent()->replace(the_case,replacement); return replacement; }
void NormalizeProcedureReturns:: do_procedure_definition( ProcedureDefinition *pd ) { ProcedureSymbol *ps = pd->get_procedure_symbol(); if (!ps) return; ProcedureType *t = to<ProcedureType>(ps->get_type()); if (!is_kind_of<CProcedureType>(t)) return; CProcedureType *ct = to<CProcedureType>(t); DataType *result = ct->get_result_type(); bool is_void = is_kind_of<VoidType>(result); for (Iter<ReturnStatement> iter = object_iterator<ReturnStatement>(pd); iter.is_valid(); iter.next()) { ReturnStatement *ret = &iter.current(); if (ret == NULL) continue; Expression *ret_expr = ret->get_return_value(); if (is_void) { if (ret_expr != NULL) { // Should not be here trash_it(remove_suif_object(ret_expr)); } } else { if (ret_expr == NULL) { // build a NULL expression to match the DataType. Expression *x = build_empty_expression(result); ret->set_return_value(x); } } } }
StatementList* get_statement_block_btw_labels(ProcedureDefinition *proc_def, CodeLabelSymbol *start_label_sym, CodeLabelSymbol *end_label_sym) { StatementList *stmt_block = create_statement_list(proc_def->get_suif_env()); for(Iter<LabelLocationStatement> iter = object_iterator<LabelLocationStatement>(proc_def->get_body()); iter.is_valid(); iter.next()) { LabelLocationStatement *start_label_loc_stmt = &iter.current(); if(start_label_loc_stmt->get_defined_label() == start_label_sym) { Statement *next_stmt = get_next_statement(start_label_loc_stmt); while(next_stmt != NULL) { if(is_a<LabelLocationStatement>(next_stmt)) { if((to<LabelLocationStatement>(next_stmt))->get_defined_label() == end_label_sym) return stmt_block; } else if(is_a<JumpStatement>(next_stmt)) { if((to<JumpStatement>(next_stmt))->get_target() == end_label_sym) return stmt_block; } stmt_block->append_statement(to<Statement>(deep_suif_clone(next_stmt))); next_stmt = get_next_statement(next_stmt); } delete stmt_block; return NULL; } } delete stmt_block; return NULL; }
// // Here are the visit methods // for the c-like printing // // All of these handle_ // will set the string in the state before returning. static String handle_static_expression(CPrintStyleModule *state, const SuifObject *obj) { Expression *expr = to<Expression>(obj); // Use the iterator over source ops and // get the classname String opname = expr->getClassName(); String return_str = String("?") + opname + "("; bool needs_comma = false; for (Iter<Expression *> iter = expr->get_source_op_iterator(); iter.is_valid(); iter.next()) { Expression *opn = iter.current(); if (needs_comma) { return_str += ","; } else { needs_comma = true; } String op = state->print_to_string(opn); return_str += op; } return_str += ")"; return(return_str); }
static String handle_static_call_statement(CPrintStyleModule *state, const SuifObject *obj) { CallStatement *expr = to<CallStatement>(obj); String addr = state->print_to_string(expr->get_callee_address()); String return_str; if (expr->get_destination() != NULL) { return_str += state->print_to_string(expr->get_destination()); return_str += " = "; } return_str += String("(") + addr + ")("; bool needs_comma = false; for (Iter<Expression *> iter = expr->get_argument_iterator(); iter.is_valid(); iter.next()) { Expression *opn = iter.current(); if (needs_comma) { return_str += ","; } else { needs_comma = true; } String op = state->print_to_string(opn); return_str += op; } return_str += ")"; return(return_str); }
void solve_li_statement_list_stmt(Statement *s){ StatementList *stmt_list = to<StatementList>(s); for (Iter<Statement*> iter = stmt_list->get_child_statement_iterator(); iter.is_valid(); iter.next()) solve_li_statement(iter.current()); }
/* return true if the symbol has a name crash with another symbol in * its parent (a symbol table). * This implementation just consider name crashes and ignore the symbol * type. */ static bool is_var_name_crashd_locally(const Symbol* symbol) { LString sname = symbol->get_name(); if (sname == emptyLString) return false; SymbolTable* symtab = to<SymbolTable>(symbol->get_parent()); if (!is_kind_of<VariableSymbol>(symbol)) return false; for (Iter<SymbolTableObject*> iter = symtab->get_symbol_table_object_iterator(); iter.is_valid(); iter.next()) { if (symbol == const_cast<const SymbolTableObject*>(iter.current())) continue; if (!is_kind_of<VariableSymbol>(iter.current())) continue; if (iter.current()->get_name() == sname) { return true; } } return false; }
void ConstQualedVarPropagationPass::do_procedure_definition(ProcedureDefinition* proc_def) { OutputInformation("Constant qualified variable propagation pass begins"); suif_map<VariableSymbol*, ValueBlock*> temp_const_defs; if (proc_def){ DefinitionBlock *proc_def_block = proc_def->get_definition_block(); for(Iter<VariableDefinition*> iter = proc_def_block->get_variable_definition_iterator(); iter.is_valid(); iter.next()){ VariableDefinition *var_def = iter.current(); VariableSymbol *var_sym = var_def->get_variable_symbol(); QualifiedType *qualed_var_type = var_sym->get_type(); if(is_a<IntegerType>(qualed_var_type->get_base_type())){ bool found = 0; for(Iter<LString> iter2 = qualed_var_type->get_qualification_iterator(); iter2.is_valid(); iter2.next()) if(iter2.current() == LString("const")) found = 1; if(found){ temp_const_defs.enter_value(var_sym, var_def->get_initialization()); } } } for(Iter<StoreVariableStatement> iter = object_iterator<StoreVariableStatement>(proc_def->get_body()); iter.is_valid(); iter.next()){ StoreVariableStatement *store_var_stmt = &iter.current(); Expression *store_var_value = store_var_stmt->get_value(); if(!is_a<IntConstant>(store_var_value)) continue; VariableSymbol *store_var_destination = store_var_stmt->get_destination(); if(!is_a<IntegerType>(store_var_destination->get_type()->get_base_type())) continue; suif_map<VariableSymbol*,ValueBlock*>::iterator iter2 = temp_const_defs.find(to<LoadVariableExpression>(store_var_value)->get_source()); if(iter2 != temp_const_defs.end()) const_qualified_scalars.enter_value(store_var_destination, (*iter2).second); } cqvp_load_variable_expression_walker walker(get_suif_env()); proc_def->walk(walker); } OutputInformation("Constant qualified variable propagation pass ends"); }
unsigned SemanticHelper::get_src_var(const ExecutionObject* exe, suif_vector<VariableSymbol*>* var_vect) { unsigned cnt = 0; for (Iter<VariableSymbol*> iter = exe->get_source_var_iterator(); iter.is_valid(); iter.next()) { cnt++; if (var_vect != 0) var_vect->push_back(iter.current()); } for (Iter<Expression*> siter = exe->get_source_op_iterator(); siter.is_valid(); siter.next()) { Expression* exp = siter.current(); if (exp == 0) continue; cnt += get_src_var(exp, var_vect); } return cnt; }
static bool is_in_lookup_list( SymbolTableObject *obj, SymbolTable* symtab) { for (Iter<SymbolTable::lookup_table_pair> it = symtab->get_lookup_table_iterator(); it.is_valid(); it.next()) { if (obj == it.current().second) return true; } return false; }
Walker::ApplyStatus sctis_multi_way_branch_statement_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); MultiWayBranchStatement *multi_way_stmt = to<MultiWayBranchStatement>(x); ProcedureDefinition *proc_def = get_procedure_definition(multi_way_stmt); TypeBuilder *tb = get_type_builder(env); BrickAnnote *end_label_annote = to<BrickAnnote>(multi_way_stmt->lookup_annote_by_name("end_label")); SuifObjectBrick *sob = to<SuifObjectBrick>(end_label_annote->get_brick(0)); CodeLabelSymbol *end_label_sym = to<CodeLabelSymbol>(sob->get_object()); Expression *decision_expr = multi_way_stmt->get_decision_operand(); CodeLabelSymbol *default_label_sym = multi_way_stmt->get_default_target(); Statement *replacement = get_statement_block_btw_labels(proc_def, default_label_sym, end_label_sym); cout << "ADDED " << print_statement(replacement); for(Iter<indexed_list<IInteger, CodeLabelSymbol*>::pair> iter = multi_way_stmt->get_case_iterator(); iter.is_valid(); iter.next()) { indexed_list<IInteger, CodeLabelSymbol*>::pair case_pair = iter.current(); Expression *condition_expr = create_binary_expression(env, tb->get_boolean_type(), String("is_equal_to"), to<Expression>(deep_suif_clone(decision_expr)), create_int_constant(env, decision_expr->get_result_type(), case_pair.first)); Statement *then_stmt = get_statement_block_btw_labels(proc_def, case_pair.second, end_label_sym); print_statement(then_stmt); replacement = create_if_statement(env, condition_expr, then_stmt, replacement); } Statement *next_stmt = get_next_statement(multi_way_stmt); bool is_removal_complete = 0; while(!is_removal_complete && next_stmt != NULL) { if(is_a<LabelLocationStatement>(next_stmt)) { if((to<LabelLocationStatement>(next_stmt))->get_defined_label() == end_label_sym) is_removal_complete = 1; } remove_statement(next_stmt); next_stmt = get_next_statement(multi_way_stmt); } multi_way_stmt->get_parent()->replace(multi_way_stmt, replacement); set_address(replacement); return Walker::Replaced; }
// Lookup a named type locally on the symbol table. // return 0 if not found. // static Type* lookup_type_locally(SymbolTable* stab, LString name) { for (Iter<SymbolTableObject*> iter = stab->get_symbol_table_object_iterator(); iter.is_valid(); iter.next()) { if (!is_kind_of<Type>(iter.current())) continue; Type* type = to<Type>(iter.current()); if (type->get_name() == name) return type; } return 0; }
Walker::ApplyStatus multi_way_branch_statement_compactor::operator () (SuifObject *x) { MultiWayBranchStatement *the_case = to<MultiWayBranchStatement>(x); // is the table already compact? if (is_compact(the_case)) return Walker::Continue; SymbolTable *scope = find_scope(x); if (!scope) return Walker::Continue; CodeLabelSymbol *default_lab = the_case->get_default_target(); // very special case - the case list is empty, so just jump to the default label if (the_case->get_case_count() == 0) { Statement *replacement = create_jump_statement(get_env(),default_lab); the_case->get_parent()->replace(the_case,replacement); set_address(replacement); return Walker::Replaced; } StatementList *replacement = create_statement_list(get_env()); Expression *operand = the_case->get_decision_operand (); remove_suif_object(operand); DataType *type = operand->get_result_type(); VariableSymbol *decision = create_variable_symbol(get_env(),get_type_builder(get_env())->get_qualified_type(type)); scope->add_symbol(decision); replacement->append_statement(create_store_variable_statement(get_env(),decision,operand)); the_case->set_default_target(0); MultiWayGroupList jump_list(get_env(),default_lab,decision);; Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); jump_list.add_element(pair.first,pair.second); iter.next(); } // we have built the new structure, now need to generate code for it jump_list.generate_code(replacement); the_case->get_parent()->replace(the_case,replacement); set_address(replacement); return Walker::Replaced; }
bool SuifValidater::is_valid_SymbolTable(SymbolTable* symtab) { if (symtab == NULL) SUIF_THROW(SuifException(String("Cannot validate a NULL SymbolTable."))); bool ok_stat = true; {for (Iter<SymbolTable::lookup_table_pair> it = symtab->get_lookup_table_iterator(); it.is_valid(); it.next()) { if (!symtab->has_symbol_table_object_member(it.current().second)) { ok_stat = false; add_error(to_id_string(symtab) + " has a lookup pair <" + it.current().first + ", " + to_id_string(it.current().second) + "> with dangling object."); } }} {for (Iter<SymbolTableObject*> it = symtab->get_symbol_table_object_iterator(); it.is_valid(); it.next()) { SymbolTableObject *sobj = it.current(); if ((sobj->get_name().length() > 0) && !is_in_lookup_list(it.current(), symtab)) { ok_stat = false; add_error(to_id_string(symtab) + " has " + to_id_string(it.current()) + " not in lookup list."); } }} return ok_stat; }
void ExportPass::execute() { assert(theEnv != NULL) ; OutputInformation("Export pass begins") ; // Get the information regarding the current procedure by looking at // the first procedure from the first file in the file set block. Iter<FileBlock*> temp = theEnv->get_file_set_block()->get_file_block_iterator() ; Iter<ProcedureDefinition*> temp2 = (temp.current())->get_definition_block()->get_procedure_definition_iterator() ; originalProcedure = temp2.current() ; assert(originalProcedure != NULL) ; // Modules have been transformed into structs so all the previous // passes work, and here we have to do a little bit of backtracking // and convert them to the straight model. BrickAnnote* rocccType = dynamic_cast<BrickAnnote*>(originalProcedure->lookup_annote_by_name("FunctionType")) ; assert(rocccType != NULL) ; IntegerBrick* valueBrick = dynamic_cast<IntegerBrick*>(rocccType->get_brick(0)) ; assert(valueBrick != NULL) ; int functionType = valueBrick->get_value().c_int() ; delete rocccType->remove_brick(0) ; delete originalProcedure->remove_annote_by_name("FunctionType") ; if (functionType == 1) // Module { // De-modulize it ConstructModuleSymbols() ; } else if (functionType == 2 || functionType == 3) // Systems { // Just create clones ConstructSystemSymbols() ; } else { assert(0 && "Trying to export something unknown") ; } ReadRepository() ; AddSymbols() ; DumpRepository() ; OutputInformation("Export pass ends") ; }
unsigned SemanticHelper::get_dst_var(const Statement* stmt, suif_vector<VariableSymbol*>* var_vect) { unsigned cnt = 0; for (Iter<VariableSymbol* > diter = stmt->get_destination_var_iterator(); diter.is_valid(); diter.next()) { cnt++; if (var_vect != NULL) var_vect->push_back(diter.current()); } return cnt; }
bool SuifValidater::is_valid( SuifObject* root) { if (root == NULL) SUIF_THROW(SuifException("Cannot validate NULL.")); bool ok_stat = is_valid_ownership(root); RefChecker rcheck(root->get_suif_env(), this); root->walk(rcheck); ok_stat &= rcheck.is_ok(); for (Iter<SymbolTable> it = object_iterator<SymbolTable>(root); it.is_valid(); it.next()) { ok_stat &= is_valid_SymbolTable(&(it.current())); } return ok_stat; }
static void handle_static_children_suif_object(WalkingMaps *walk, SuifObject *obj) { // use the object iterator to find all suiffobjects. // check to see that the parent is ME for (Iter<SuifObject> iter = collect_instance_objects<SuifObject>(obj); iter.is_valid(); iter.next()) { // list<SuifObject *>::iterator iter = the_list->begin(); // for (; iter != the_list->end(); iter++) { SuifObject *child = &iter.current(); if (child == 0 ) continue; suif_assert(child->get_parent() == obj); walk->get_process_map()->apply(child); if (walk->is_done()) return; } }
void AvoidFileScopeCollisions::do_file_set_block( FileSetBlock* file_set_block ) { list<SymbolTable*> file_scope_tables; for (Iter<FileBlock*> iter = file_set_block->get_file_block_iterator(); iter.is_valid(); iter.next()) { file_scope_tables.push_back(iter.current()->get_symbol_table()); } file_scope_tables.push_back(file_set_block->get_file_set_symbol_table()); CollisionAvoider walker(get_suif_env(), file_set_block->get_external_symbol_table(), &file_scope_tables, (file_set_block->get_file_block(0))-> get_source_file_name(), false); file_set_block->walk(walker); }
void MarkGuardedFors:: do_procedure_definition(ProcedureDefinition *pd) { for (Iter<ForStatement> iter = object_iterator<ForStatement>(pd); iter.is_valid(); iter.next()) { ForStatement *the_for = &iter.current(); if (is_for_statement_guarded(the_for)) continue; IInteger ii = evaluate_for_statement_entry_test(the_for); if (ii.is_undetermined()) return; if (ii == 0) return; if (ii == 1) { set_for_statement_guarded(the_for); } } }
list<Statement*>* form_child_stmt_list(Statement *s, list<Statement*>* result_list = 0){ if(!result_list) result_list = new list<Statement*>; if(!s) return result_list; if(is_a<StatementList>(s)) for(Iter<Statement*> iter = (to<StatementList>(s))->get_statement_iterator(); iter.is_valid(); iter.next()) form_child_stmt_list(iter.current(), result_list); else result_list->push_back(s); return result_list; }
static String handle_static_eval_statement(CPrintStyleModule *state, const SuifObject *obj) { EvalStatement *stmt = to<EvalStatement>(obj); String return_str = "Eval("; bool is_first = true; for (Iter<Expression*> iter = stmt->get_expression_iterator(); iter.is_valid(); iter.next()) { if (!is_first) return_str += ", "; Expression *expr = iter.current(); return_str += state->print_to_string(expr); is_first = false; } return(return_str); }
void InstanceFieldsLayoutPass::mangle_fields( ClassType* ctype ) { BasicSymbolTable* symtab = ctype->get_group_symbol_table(); Iter<SymbolTableObject*> iter = symtab->get_symbol_table_object_iterator(); while( iter.is_valid() ) { InstanceFieldSymbol* fsym = to<InstanceFieldSymbol>( iter.current() ); if ( _verbose ) { // cout << fsym->get_name().c_str() << " -> " // << mangled_name(fsym).c_str() << endl; } symtab->change_name( fsym, mangled_name(fsym) ); iter.next(); } }
void form_worklist(Statement *s){ if(!s) return; if(is_a<IfStatement>(s)){ form_worklist((to<IfStatement>(s))->get_then_part()); form_worklist((to<IfStatement>(s))->get_else_part()); worklist->push_back(to<IfStatement>(s)); }else if(is_a<CForStatement>(s)) form_worklist((to<CForStatement>(s))->get_body()); else if(is_a<WhileStatement>(s)) form_worklist((to<WhileStatement>(s))->get_body()); else if(is_a<ScopeStatement>(s)) form_worklist((to<ScopeStatement>(s))->get_body()); else if(is_a<StatementList>(s)) for(Iter<Statement*> iter = (to<StatementList>(s))->get_statement_iterator(); iter.is_valid(); iter.next()) form_worklist(iter.current()); }
void M2c::process_sym_table(SymTable *st) { bool st_is_private = is_private(st); Iter<SymbolTableObject*> iter = st->get_symbol_table_object_iterator(); for (/* iter */; iter.is_valid(); iter.next()) { SymbolTableObject *the_sto = iter.current(); if (is_kind_of<VariableSymbol>(the_sto)) { if (is_kind_of<ParameterSymbol>(the_sto)) continue; // don't shadow an arg! VarSym *v = to<VariableSymbol>(the_sto); if (!is_global(st)) { printer->print_var_def(v, false); } else if (v->get_definition() != NULL) { postponed_vars.push_back(v); printer->print_var_def(v, true); } else { claim(is_external(v)); fprintf(out, "extern "); printer->print_sym_decl(v); fprintf(out, ";\n"); } } else if (is_kind_of<ProcedureSymbol>(the_sto)) { if (st_is_private) fputs("static ", out); printer->print_proc_decl(to<ProcedureSymbol>(the_sto)); } else if (is_kind_of<Type>(the_sto)) { if (is_kind_of<EnumeratedType>(the_sto) || (is_kind_of<GroupType>(the_sto) && to<GroupType>(the_sto)->get_is_complete())) { printer->print_type(to<Type>(the_sto)); fprintf(out, ";\n"); } } } }