예제 #1
0
파일: inliner.C 프로젝트: alexjohn1362/rose
     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);
             }
        }
예제 #2
0
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;
}
예제 #3
0
// 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);
        }
   }
예제 #4
0
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());
}