virtual void visit(SgNode* n) { SgReturnStmt* rs = isSgReturnStmt(n); if (rs) { // std::cout << "Converting return statement " << rs->unparseToString(); // std::cout << " into possible assignment to " << where_to_write_answer->unparseToString(); // std::cout << " and jump to " << label->get_name().getString() << std::endl; SgExpression* return_expr = rs->get_expression(); SgBasicBlock* block = SageBuilder::buildBasicBlock(); // printf ("Building IR node #1: new SgBasicBlock = %p \n",block); if (return_expr) { SgExpression* assignment = generateAssignmentMaybe(where_to_write_answer,return_expr); if (where_to_write_answer) where_to_write_answer->set_parent(assignment); if (return_expr != assignment) return_expr->set_parent(assignment); SgStatement* assign_stmt = SageBuilder::buildExprStatement(assignment); SageInterface::appendStatement(assign_stmt, block); } // block->get_statements().push_back(new SgGotoStatement(SgNULL_FILE, label)); SgGotoStatement* gotoStatement = new SgGotoStatement(SgNULL_FILE, label); gotoStatement->set_endOfConstruct(SgNULL_FILE); ROSE_ASSERT(n->get_parent() != NULL); SageInterface::appendStatement(gotoStatement, block); isSgStatement(n->get_parent())->replace_statement(rs, block); block->set_parent(n->get_parent()); ROSE_ASSERT(gotoStatement->get_parent() != NULL); } }
bool ClangToSageTranslator::VisitFunctionDecl(clang::FunctionDecl * function_decl, SgNode ** node) { #if DEBUG_VISIT_DECL std::cerr << "ClangToSageTranslator::VisitFunctionDecl" << std::endl; #endif bool res = true; // FIXME: There is something weird here when try to Traverse a function reference in a recursive function (when first Traverse is not complete) // It seems that it tries to instantiate the decl inside the function... // It may be faster to recode from scratch... // If I am not wrong this have been fixed.... SgName name(function_decl->getNameAsString()); SgType * ret_type = buildTypeFromQualifiedType(function_decl->getResultType()); SgFunctionParameterList * param_list = SageBuilder::buildFunctionParameterList_nfi(); applySourceRange(param_list, function_decl->getSourceRange()); // FIXME find the good SourceRange (should be stored by Clang...) for (unsigned i = 0; i < function_decl->getNumParams(); i++) { SgNode * tmp_init_name = Traverse(function_decl->getParamDecl(i)); SgInitializedName * init_name = isSgInitializedName(tmp_init_name); if (tmp_init_name != NULL && init_name == NULL) { std::cerr << "Runtime error: tmp_init_name != NULL && init_name == NULL" << std::endl; res = false; continue; } param_list->append_arg(init_name); } if (function_decl->isVariadic()) { SgName empty = ""; SgType * ellipses_type = SgTypeEllipse::createType(); param_list->append_arg(SageBuilder::buildInitializedName_nfi(empty, ellipses_type, NULL)); } SgFunctionDeclaration * sg_function_decl; if (function_decl->isThisDeclarationADefinition()) { sg_function_decl = SageBuilder::buildDefiningFunctionDeclaration(name, ret_type, param_list, NULL); sg_function_decl->set_definingDeclaration(sg_function_decl); if (function_decl->isVariadic()) { sg_function_decl->hasEllipses(); } if (!function_decl->hasBody()) { std::cerr << "Defining function declaration without body..." << std::endl; res = false; } /* if (sg_function_decl->get_definition() != NULL) SageInterface::deleteAST(sg_function_decl->get_definition()); SgFunctionDefinition * function_definition = new SgFunctionDefinition(sg_function_decl, NULL); SgInitializedNamePtrList & init_names = param_list->get_args(); SgInitializedNamePtrList::iterator it; for (it = init_names.begin(); it != init_names.end(); it++) { (*it)->set_scope(function_definition); SgSymbolTable * st = function_definition->get_symbol_table(); ROSE_ASSERT(st != NULL); SgVariableSymbol * tmp_sym = new SgVariableSymbol(*it); st->insert((*it)->get_name(), tmp_sym); } */ SgFunctionDefinition * function_definition = sg_function_decl->get_definition(); if (sg_function_decl->get_definition()->get_body() != NULL) SageInterface::deleteAST(sg_function_decl->get_definition()->get_body()); SageBuilder::pushScopeStack(function_definition); SgNode * tmp_body = Traverse(function_decl->getBody()); SgBasicBlock * body = isSgBasicBlock(tmp_body); SageBuilder::popScopeStack(); if (tmp_body != NULL && body == NULL) { std::cerr << "Runtime error: tmp_body != NULL && body == NULL" << std::endl; res = false; } else { function_definition->set_body(body); body->set_parent(function_definition); applySourceRange(function_definition, function_decl->getSourceRange()); } sg_function_decl->set_definition(function_definition); function_definition->set_parent(sg_function_decl); SgFunctionDeclaration * first_decl; if (function_decl->getFirstDeclaration() == function_decl) { SgFunctionParameterList * param_list_ = SageBuilder::buildFunctionParameterList_nfi(); setCompilerGeneratedFileInfo(param_list_); SgInitializedNamePtrList & init_names = param_list->get_args(); SgInitializedNamePtrList::iterator it; for (it = init_names.begin(); it != init_names.end(); it++) { SgInitializedName * init_param = new SgInitializedName(**it); setCompilerGeneratedFileInfo(init_param); param_list_->append_arg(init_param); } first_decl = SageBuilder::buildNondefiningFunctionDeclaration(name, ret_type, param_list_, NULL); setCompilerGeneratedFileInfo(first_decl); first_decl->set_parent(SageBuilder::topScopeStack()); first_decl->set_firstNondefiningDeclaration(first_decl); if (function_decl->isVariadic()) first_decl->hasEllipses(); } else { SgSymbol * tmp_symbol = GetSymbolFromSymbolTable(function_decl->getFirstDeclaration()); SgFunctionSymbol * symbol = isSgFunctionSymbol(tmp_symbol); if (tmp_symbol != NULL && symbol == NULL) { std::cerr << "Runtime error: tmp_symbol != NULL && symbol == NULL" << std::endl; res = false; } if (symbol != NULL) first_decl = isSgFunctionDeclaration(symbol->get_declaration()); } sg_function_decl->set_firstNondefiningDeclaration(first_decl); first_decl->set_definingDeclaration(sg_function_decl); } else { sg_function_decl = SageBuilder::buildNondefiningFunctionDeclaration(name, ret_type, param_list, NULL); if (function_decl->isVariadic()) sg_function_decl->hasEllipses(); SgInitializedNamePtrList & init_names = param_list->get_args(); SgInitializedNamePtrList::iterator it; for (it = init_names.begin(); it != init_names.end(); it++) { (*it)->set_scope(SageBuilder::topScopeStack()); } if (function_decl->getFirstDeclaration() != function_decl) { SgSymbol * tmp_symbol = GetSymbolFromSymbolTable(function_decl->getFirstDeclaration()); SgFunctionSymbol * symbol = isSgFunctionSymbol(tmp_symbol); if (tmp_symbol != NULL && symbol == NULL) { std::cerr << "Runtime error: tmp_symbol != NULL && symbol == NULL" << std::endl; res = false; } SgFunctionDeclaration * first_decl = NULL; if (symbol != NULL) { first_decl = isSgFunctionDeclaration(symbol->get_declaration()); } else { // FIXME Is it correct? SgNode * tmp_first_decl = Traverse(function_decl->getFirstDeclaration()); first_decl = isSgFunctionDeclaration(tmp_first_decl); ROSE_ASSERT(first_decl != NULL); // ROSE_ASSERT(!"We should have see the first declaration already"); } if (first_decl != NULL) { if (first_decl->get_firstNondefiningDeclaration() != NULL) sg_function_decl->set_firstNondefiningDeclaration(first_decl->get_firstNondefiningDeclaration()); else { ROSE_ASSERT(first_decl->get_firstNondefiningDeclaration() != NULL); } } else { ROSE_ASSERT(!"First declaration not found!"); } } else { sg_function_decl->set_firstNondefiningDeclaration(sg_function_decl); } } ROSE_ASSERT(sg_function_decl->get_firstNondefiningDeclaration() != NULL); /* // TODO Fix problem with function symbols... SgSymbol * symbol = GetSymbolFromSymbolTable(function_decl); if (symbol == NULL) { SgFunctionSymbol * func_sym = new SgFunctionSymbol(isSgFunctionDeclaration(sg_function_decl->get_firstNondefiningDeclaration())); SageBuilder::topScopeStack()->insert_symbol(name, func_sym); } */ // ROSE_ASSERT(GetSymbolFromSymbolTable(function_decl) != NULL); *node = sg_function_decl; return VisitDeclaratorDecl(function_decl, node) && res; }
// Move variables declared in a for statement to just outside that statement. void moveForDeclaredVariables(SgNode* root) { vector<SgForStatement*> for_statements; FindForStatementsVisitor(for_statements).traverse(root, preorder); for (unsigned int i = 0; i < for_statements.size(); ++i) { SgForStatement* stmt = for_statements[i]; #ifdef FD_DEBUG cout << "moveForDeclaredVariables: " << stmt->unparseToString() << endl; #endif SgForInitStatement* init = stmt->get_for_init_stmt(); if (!init) continue; SgStatementPtrList& inits = init->get_init_stmt(); vector<SgVariableDeclaration*> decls; for (SgStatementPtrList::iterator j = inits.begin(); j != inits.end(); ++j) { SgStatement* one_init = *j; if (isSgVariableDeclaration(one_init)) { decls.push_back(isSgVariableDeclaration(one_init)); } } if (decls.empty()) continue; SgStatement* parent = isSgStatement(stmt->get_parent()); assert (parent); SgBasicBlock* bb = new SgBasicBlock(SgNULL_FILE); stmt->set_parent(bb); bb->set_parent(parent); SgStatementPtrList ls; for (unsigned int j = 0; j < decls.size(); ++j) { for (SgInitializedNamePtrList::iterator k = decls[j]->get_variables().begin(); k != decls[j]->get_variables().end(); ++k) { #ifdef FD_DEBUG cout << "Working on variable " << (*k)->get_name().getString() << endl; #endif SgVariableSymbol* sym = new SgVariableSymbol(*k); bb->insert_symbol((*k)->get_name(), sym); (*k)->set_scope(bb); SgAssignInitializer* kinit = 0; if (isSgAssignInitializer((*k)->get_initializer())) { kinit = isSgAssignInitializer((*k)->get_initializer()); (*k)->set_initializer(0); } if (kinit) { SgVarRefExp* vr = new SgVarRefExp(SgNULL_FILE, sym); vr->set_endOfConstruct(SgNULL_FILE); vr->set_lvalue(true); SgAssignOp* assignment = new SgAssignOp(SgNULL_FILE,vr,kinit->get_operand()); vr->set_parent(assignment); kinit->get_operand()->set_parent(assignment); SgExprStatement* expr = new SgExprStatement(SgNULL_FILE, assignment); assignment->set_parent(expr); ls.push_back(expr); expr->set_parent(init); } } #if 0 SgStatementPtrList::iterator fiiter = std::find(inits.begin(), inits.end(), decls[j]); assert (fiiter != inits.end()); size_t idx = fiiter - inits.begin(); inits.erase(inits.begin() + idx); inits.insert(inits.begin() + idx, ls.begin(), ls.end()); #endif bb->get_statements().push_back(decls[j]); decls[j]->set_parent(bb); } inits = ls; bb->get_statements().push_back(stmt); // printf ("In moveForDeclaredVariables(): parent = %p = %s bb = %p stmt = %p = %s \n",parent,parent->class_name().c_str(),bb,stmt,stmt->class_name().c_str()); ROSE_ASSERT(stmt->get_parent() == bb); parent->replace_statement(stmt, bb); } }
void PRE::addEdgeInsertionPoints(PRE::ControlFlowGraph& controlflow) { // printf ("In addEdgeInsertionPoints: controlflow.graph.vertices().size() = %zu \n",controlflow.graph.vertices().size()); // printf ("In addEdgeInsertionPoints: controlflow.edge_insertion_point.size() = %zu \n",controlflow.edge_insertion_point.size()); VertexIter i = controlflow.graph.vertices().begin(), iend = controlflow.graph.vertices().end(); for (; i != iend; ++i) { // printf ("vertexCount = %d \n",vertexCount++); OutEdgeIter out = controlflow.graph.out_edges(*i).begin(), outend = controlflow.graph.out_edges(*i).end(); // printf ("Problem location: controlflow.node_statements[*i] = %p \n",&(controlflow.node_statements[*i])); const vector<SgNode*>& stmts = controlflow.node_statements[*i]; SgNode* last_stmt = stmts.empty() ? 0 : stmts[stmts.size() - 1]; int out_edge_count = distance(out, outend); SgStatement* expr_parent = 0; // printf ("stmts.size() = %zu last_stmt = %p expr_parent = %p \n",stmts.size(),last_stmt,expr_parent); // Wouldn't this make more sense as a while loop? for (vector<SgNode*>::const_iterator j = stmts.begin(); j != stmts.end(); ++j) { ROSE_ASSERT((*j) != NULL); #if 0 if ((*j)->get_parent() == NULL) { (*j)->get_file_info()->display("Location of error: debug"); printf ("Error: statement = %s \n",(*j)->unparseToString().c_str()); } else { ROSE_ASSERT((*j)->get_parent() != NULL); // printf ("Statement at vertex (*i): (*j)->class_name() = %s (*j)->get_parent()->class_name()\n",(*j)->class_name().c_str(),(*j)->get_parent()->class_name().c_str()); } #endif if (expr_parent) continue; if (isSgExpression(*j)) { expr_parent = isSgStatement((*j)->get_parent()); ROSE_ASSERT (expr_parent); } else { if (isSgExprStatement(*j)) { expr_parent = isSgStatement((*j)->get_parent()); if (isSgBasicBlock(expr_parent) || isSgForInitStatement(expr_parent)) expr_parent = 0; } } } // printf ("out_edge_count = %d \n",out_edge_count); // printf ("expr_parent = %p = %s \n",expr_parent,(expr_parent != NULL) ? expr_parent->class_name().c_str() : "NULL"); if (!expr_parent) { // printf ("Fixup the expr_parent to be the last_stmt = %p \n",last_stmt); expr_parent = isSgStatement(last_stmt); } #if 0 // DQ (3/17/2006): It is a problem if at this point the expr_parent is NULL if (expr_parent == NULL) { printf ("Warning expr_parent == NULL \n"); } #endif if (out_edge_count == 1 && !isSgForStatement(expr_parent)) { #if 0 // printf ("Edge count == 1: and not a SgForStatement, adding and edge using %p \n",expr_parent); if (expr_parent == NULL) { printf ("Warning adding an edge using a NULL pointer! at %p \n",&(controlflow.edge_insertion_point[*out])); } #endif controlflow.edge_insertion_point[*out] = make_pair(expr_parent, (isSgGotoStatement(expr_parent) ? /* Put insertion before goto statements but after other statement types */ true : false)); } else { if (out_edge_count == 1 && isSgForStatement(expr_parent)) { // Increment of for statement controlflow.edge_insertion_point[*out] = make_pair(isSgForStatement(expr_parent)->get_increment(),false); // Put in after expression using operator, } else { if (out_edge_count >= 2) { for (; out != outend; ++out) { pair<SgStatement*, bool> insert_point; CFGConfig::EdgeType kind = controlflow.edge_type[*out]; // printf ("CFGConfig::EdgeType kind = %d \n",(int)kind); try_next_ancestor: ROSE_ASSERT(expr_parent != NULL); switch (expr_parent->variantT()) { case V_SgDoWhileStmt: if (kind == CFGConfig::COND_FALSE) { insert_point = make_pair(expr_parent, false); } else { // DQ (3/13/2006): Make this an error (partly as just a test) // FIXME -- We can't really use // do-while in tests anymore, since // there isn't a good way to put // something on the true branch of // the test printf ("kind != CFGConfig::COND_FALSE in SgDoWhileStmt \n"); ROSE_ASSERT(false); } break; case V_SgIfStmt: if (kind == CFGConfig::COND_TRUE) { insert_point = make_pair(isSgIfStmt(expr_parent)->get_true_body(), true); } else { if (isSgIfStmt(expr_parent)->get_false_body() == NULL) { SgBasicBlock* bb = SageBuilder::buildBasicBlock(); isSgIfStmt(expr_parent)->set_false_body(bb); bb->set_parent(expr_parent); } ROSE_ASSERT (isSgIfStmt(expr_parent)->get_false_body()); insert_point = make_pair(isSgIfStmt(expr_parent)->get_false_body(), true); } break; case V_SgWhileStmt: if (kind == CFGConfig::COND_TRUE) { insert_point = make_pair(isSgWhileStmt(expr_parent)->get_body(), true); } else { insert_point = make_pair(expr_parent, false); } break; case V_SgSwitchStatement: assert (!"switch FIXME"); break; case V_SgForStatement: // printf ("Found a SgForStatement, but this should not be used now the the conditional test is a SgExprStatement \n"); // ROSE_ASSERT(false); if (kind == CFGConfig::COND_TRUE) { insert_point = make_pair(isSgForStatement(expr_parent)->get_loop_body(), true); } else { // DQ (3/17/2006): this effects the placement of the cachevar__10 = (_var_0 + 15); in pass3.C ROSE_ASSERT(expr_parent != NULL); insert_point = make_pair(expr_parent, false); // insert_point = make_pair(expr_parent, true); } break; #if 0 // DQ (3/13/2006): Added case for SgExpressionStatment, since it is now the conditonal // test in a SgForStatement (due to a recent change in the IR to support such things // which are leagal code in C and C++). case V_SgExprStatement: printf ("Found a SgExprStatement, likely the test in a SgForStatment or such \n"); ROSE_ASSERT (false); ROSE_ASSERT(isSgForStatement(expr_parent->get_parent()) != NULL); ROSE_ASSERT(isSgForStatement(expr_parent->get_parent())->get_test() == expr_parent); if (kind == CFGConfig::COND_TRUE) { printf ("Building an edge to the for loop body \n"); insert_point = make_pair(isSgForStatement(expr_parent->get_parent())->get_loop_body(), true); } else { insert_point = make_pair(expr_parent, false); } break; #endif case V_SgExprStatement: case V_SgGotoStatement: case V_SgLabelStatement: { expr_parent = isSgStatement(expr_parent->get_parent()); goto try_next_ancestor; } default: cerr << "Unknown variant " << expr_parent->sage_class_name() << endl; expr_parent->get_file_info()->display("Location in input code"); ROSE_ASSERT (false); break; } if (insert_point.first) controlflow.edge_insertion_point[*out] = insert_point; } } else { // out_edge_count == 0 } } } } EdgeIter ei = controlflow.graph.edges().begin(), eend = controlflow.graph.edges().end(); for (; ei != eend; ++ei) { if (!controlflow.edge_insertion_point[*ei].first) { Vertex src = controlflow.graph.source(*ei); if (controlflow.graph.out_edges(src).size() == 1 && !controlflow.node_statements[src].empty()) { vector<SgNode*> stmts = controlflow.node_statements[src]; controlflow.edge_insertion_point[*ei] = make_pair(stmts[stmts.size() - 1], false); } } } // printf ("Leaving addEdgeInsertionPoints: controlflow.graph.vertices().size() = %zu \n",controlflow.graph.vertices().size()); // printf ("Leaving addEdgeInsertionPoints: controlflow.edge_insertion_point.size() = %zu \n",controlflow.edge_insertion_point.size()); }