Пример #1
0
  NodeQuerySynthesizedAttributeType
NodeQuery::querySolverVariableDeclarations (SgNode * astNode)
{
  ROSE_ASSERT (astNode != 0);
  NodeQuerySynthesizedAttributeType returnNodeList;

  switch (astNode->variantT ())
  {

    case V_SgVariableDeclaration:
      returnNodeList.push_back (astNode);
      break;
    case V_SgFunctionDeclaration:
    case V_SgMemberFunctionDeclaration:
      {
        SgFunctionDeclaration * sageFunctionDeclaration =
          isSgFunctionDeclaration (astNode);
        ROSE_ASSERT (sageFunctionDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList =
          sageFunctionDeclaration->get_args ();


        typedef SgInitializedNamePtrList::iterator variableIterator;

        for (variableIterator variableListElement =
            sageInitializedNameList.begin ();
            variableListElement != sageInitializedNameList.end ();
            ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          //SgVariableDeclaration* sageVariableDeclaration = isSgVariableDeclaration((elmVar.get_declaration())->copy());
          //ROSE_ASSERT(sageVariableDeclaration != NULL); 

          //if( sageVariableDeclaration != NULL)

          //AS (9/26/03) I must put an object of type const SgDeclarationStatement into the list because
          //             I have no other way of finding the SgVariableDeclaration in the arguments. This is safe
          //             because arguments are Variable Declarations, but puts unwelcome limits on use of returned
          //             list because of it's constantness.
          ROSE_ASSERT (elmVar != NULL);
          returnNodeList.push_back (elmVar->get_declaration ());
          //returnNodeList.push_back (sageVariableDeclaration);

        }

        break;
      }

    default:
      {
        // DQ (8/20/2005): Added default to avoid compiler warnings about unrepresented cases
      }
  }                             /* End switch-case */

  return returnNodeList;
}                               /* End function querySolverVariableDeclarations() */
Пример #2
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameArgumentNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

  SgFunctionDeclaration *sageFunctionDeclaration =
    isSgFunctionDeclaration (astNode);

  if (sageFunctionDeclaration != NULL)
    {

      typedef SgInitializedNamePtrList::iterator argumentIterator;
      SgInitializedNamePtrList sageNameList = sageFunctionDeclaration->get_args ();
      int countArguments = 0;
      for (argumentIterator i = sageNameList.begin();
           i != sageNameList.end(); ++i)
        {
          SgInitializedName* elementNode = *i;
          ROSE_ASSERT (elementNode != NULL);

          string sageArgument(elementNode->get_name().str());

          returnNameList.push_back(sageArgument.c_str());

          countArguments += 1;
        }
#if DEBUG_NAMEQUERY
      printf ("\nHere is a function declaration :Line = %d Columns = %d \n",
              ROSE::getLineNumber (isSgLocatedNode (astNode)),
              ROSE::getColumnNumber (isSgLocatedNode (astNode)));
      cout << "The filename is:" << ROSE::
        getFileName (isSgLocatedNode (astNode)) << endl;
      cout << "The count of arguments is: " << countArguments << endl;
#endif
    }

  return returnNameList;
}                               /* End function queryNameArgumentNames() */
Пример #3
0
  NodeQuerySynthesizedAttributeType
NodeQuery::querySolverVariableTypes (SgNode * astNode)
{
  ROSE_ASSERT (astNode != NULL);
  NodeQuerySynthesizedAttributeType returnNodeList;
  /*
     SgVariableDeclaration* sageVariableDeclaration = isSgVariableDeclaration(astNode);

     if(sageVariableDeclaration != NULL)
     {
     SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables();


     printf ("\nHere is a function declaration :Line = %d Columns = %d \n", ROSE:: getLineNumber (isSgLocatedNode(astNode) ), ROSE:: getColumnNumber ( isSgLocatedNode(astNode) ));
     cout << "The filename is:" << ROSE::getFileName(isSgLocatedNode(astNode)) << endl;


     typedef SgInitializedNamePtrList::iterator LI;

     for ( LI i = sageInitializedNameList.begin(); i != sageInitializedNameList.end(); ++i) {
     SgType* sageElementType = i->get_type();
     ROSE_ASSERT( sageElementType != NULL);

     cout << "The class name is: " << sageElementType->sage_class_name() << endl;
     returnNodeList.push_back( sageElementType );

     }
     cout << endl << "End printout of this Initialized Name list" << endl;


     }

   */
  // SgVarRefExp *sageVarRefExp = isSgVarRefExp (astNode);

  switch (astNode->variantT ())
  {

    case V_SgVariableDeclaration:
      {
        SgVariableDeclaration *sageVariableDeclaration =
          isSgVariableDeclaration (astNode);
        ROSE_ASSERT (sageVariableDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList =
          sageVariableDeclaration->get_variables ();

#if DEBUG_NODEQUERY
        printf ("\nIn filename: %s ",
            ROSE::getFileName (isSgLocatedNode (astNode)));
        printf ("\nHere is a variable :Line = %d Columns = %d \n",
            ROSE::getLineNumber (isSgLocatedNode (astNode)),
            ROSE::getColumnNumber (isSgLocatedNode (astNode)));
        //cout << "The typename of the variable is: " << typeName << endl;
#endif

        typedef SgInitializedNamePtrList::iterator variableIterator;
        SgType *typeNode;

        for (variableIterator variableListElement =
            sageInitializedNameList.begin ();
            variableListElement != sageInitializedNameList.end ();
            ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          ROSE_ASSERT (elmVar != NULL);
          typeNode = elmVar->get_type ();
          ROSE_ASSERT (typeNode != NULL);
          returnNodeList.push_back (typeNode);
        }
        break;
      }                         /* End case V_SgVariableDeclaration */

    case V_SgFunctionDeclaration:
    case V_SgMemberFunctionDeclaration:
      {
        SgFunctionDeclaration * sageFunctionDeclaration =
          isSgFunctionDeclaration (astNode);
        ROSE_ASSERT (sageFunctionDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList =
          sageFunctionDeclaration->get_args ();
        SgType *typeNode;

        typedef SgInitializedNamePtrList::iterator variableIterator;

        for (variableIterator variableListElement =
            sageInitializedNameList.begin ();
            variableListElement != sageInitializedNameList.end ();
            ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          ROSE_ASSERT (elmVar != NULL);
          typeNode = elmVar->get_type ();
          ROSE_ASSERT (typeNode != NULL);
          returnNodeList.push_back (typeNode);

        }

        break;
      }

    default:
      {
        // DQ (8/20/2005): Added default to avoid compiler warnings about unrepresented cases
      }
  }                             /* End switch case astNode */



  return returnNodeList;
}                               /* End function querySolverType() */
Пример #4
0
void SystemDependenceGraph::build()
{
    boost::unordered_map<CFGVertex, Vertex> cfgVerticesToSdgVertices;
    boost::unordered_map<SgNode*, Vertex>   astNodesToSdgVertices;

    //map<SgFunctionCallExp*, vector<SDGNode*> > funcCallToArgs;

    vector<CallSiteInfo> functionCalls;


    map<SgNode*, vector<Vertex> > actualInParameters;
    map<SgNode*, vector<Vertex> > actualOutParameters;

    map<SgNode*, Vertex> formalInParameters;
    map<SgNode*, Vertex> formalOutParameters;

    vector<SgFunctionDefinition*> funcDefs = 
        SageInterface::querySubTree<SgFunctionDefinition>(project_, V_SgFunctionDefinition);
    foreach (SgFunctionDefinition* funcDef, funcDefs)
    {
        SgFunctionDeclaration* funcDecl = funcDef->get_declaration();

        CFG* cfg = new CFG(funcDef, cfgNodefilter_);
        functionsToCFGs_[funcDecl] = cfg;

        // For each function, build an entry node for it.
        SDGNode* entry = new SDGNode(SDGNode::Entry);
        entry->astNode = funcDef;
        //entry->funcDef = funcDef;
        Vertex entryVertex = addVertex(entry);
        functionsToEntries_[funcDecl] = entryVertex;

        // Add all out formal parameters to SDG.
        const SgInitializedNamePtrList& formalArgs = funcDecl->get_args();
        foreach (SgInitializedName* initName, formalArgs)
        {
            // If the parameter is passed by reference, create a formal-out node.
            if (isParaPassedByRef(initName->get_type()))
            {
                SDGNode* formalOutNode = new SDGNode(SDGNode::FormalOut);
                formalOutNode->astNode = initName;
                Vertex formalOutVertex = addVertex(formalOutNode);
                formalOutParameters[initName] = formalOutVertex;

                // Add a CD edge from call node to this formal-out node.
                addTrueCDEdge(entryVertex, formalOutVertex);
            }
        }

        // A vertex representing the returned value.
        Vertex returnVertex;

        // If the function returns something, build a formal-out node.
        if (!isSgTypeVoid(funcDecl->get_type()->get_return_type()))
        {
            SDGNode* formalOutNode = new SDGNode(SDGNode::FormalOut);
            // Assign the function declaration to the AST node of this vertex to make
            // it possible to classify this node into the subgraph of this function.
            formalOutNode->astNode = funcDecl;
            returnVertex = addVertex(formalOutNode);
            formalOutParameters[funcDecl] = returnVertex;

            // Add a CD edge from call node to this formal-out node.
            addTrueCDEdge(entryVertex, returnVertex);
        }

        // Add all CFG vertices to SDG.
        foreach (CFGVertex cfgVertex, boost::vertices(*cfg))
        {
            if (cfgVertex == cfg->getEntry() || cfgVertex == cfg->getExit())
                continue;

            SgNode* astNode = (*cfg)[cfgVertex]->getNode();

            // If this node is an initialized name and it is a parameter, make it 
            // as a formal in node.
            SgInitializedName* initName = isSgInitializedName(astNode);
            if (initName && isSgFunctionParameterList(initName->get_parent()))
            {
                SDGNode* formalInNode = new SDGNode(SDGNode::FormalIn);
                formalInNode->astNode = initName;
                Vertex formalInVertex = addVertex(formalInNode);
                formalInParameters[initName] = formalInVertex;

                cfgVerticesToSdgVertices[cfgVertex] = formalInVertex;
                astNodesToSdgVertices[astNode] = formalInVertex;

                // Add a CD edge from call node to this formal-in node.
                addTrueCDEdge(entryVertex, formalInVertex);
                continue;
            }

            // Add a new node to SDG.
            SDGNode* newSdgNode = new SDGNode(SDGNode::ASTNode);
            //newSdgNode->cfgNode = (*cfg)[cfgVertex];
            newSdgNode->astNode = astNode;
            Vertex sdgVertex = addVertex(newSdgNode);

            cfgVerticesToSdgVertices[cfgVertex] = sdgVertex;
            astNodesToSdgVertices[astNode] = sdgVertex;


            // Connect a vertex containing the return statement to the formal-out return vertex.
            if (isSgReturnStmt(astNode)
                    || isSgReturnStmt(astNode->get_parent()))
            {
                SDGEdge* newEdge = new SDGEdge(SDGEdge::DataDependence);
                addEdge(sdgVertex, returnVertex, newEdge);                
            }

            // If this CFG node contains a function call expression, extract its all parameters
            // and make them as actual-in nodes.

            if (SgFunctionCallExp* funcCallExpr = isSgFunctionCallExp(astNode))
            {
                CallSiteInfo callInfo;
                callInfo.funcCall = funcCallExpr;
                callInfo.vertex = sdgVertex;

                // Change the node type.
                newSdgNode->type = SDGNode::FunctionCall;
                vector<SDGNode*> argsNodes;

                // Get the associated function declaration.
                SgFunctionDeclaration* funcDecl = funcCallExpr->getAssociatedFunctionDeclaration();
                
                if (funcDecl == NULL) 
                    continue;
                    
                ROSE_ASSERT(funcDecl);
                const SgInitializedNamePtrList& formalArgs = funcDecl->get_args();

                SgExprListExp* args = funcCallExpr->get_args();
                const SgExpressionPtrList& actualArgs = args->get_expressions();
                
                if (formalArgs.size() != actualArgs.size())
                {
                    cout << "The following function has variadic arguments:\n";
                    cout << funcDecl->get_file_info()->get_filename() << endl;
                    cout << funcDecl->get_name() << formalArgs.size() << " " << actualArgs.size() << endl;
                    continue;
                }

                for (int i = 0, s = actualArgs.size(); i < s; ++i)
                {
                    // Make sure that this parameter node is added to SDG then we
                    // change its node type from normal AST node to a ActualIn arg.
                    ROSE_ASSERT(astNodesToSdgVertices.count(actualArgs[i]));

                    Vertex paraInVertex = astNodesToSdgVertices.at(actualArgs[i]);
                    SDGNode* paraInNode = (*this)[paraInVertex]; 
                    paraInNode->type = SDGNode::ActualIn;

                    actualInParameters[formalArgs[i]].push_back(paraInVertex);
                    callInfo.inPara.push_back(paraInVertex);

                    // Add a CD edge from call node to this actual-in node.
                    addTrueCDEdge(sdgVertex, paraInVertex);

                    // If the parameter is passed by reference, create a parameter-out node.
                    if (isParaPassedByRef(formalArgs[i]->get_type()))
                    {
                        SDGNode* paraOutNode = new SDGNode(SDGNode::ActualOut);
                        paraOutNode->astNode = actualArgs[i];
                        //argsNodes.push_back(paraInNode);

                        // Add an actual-out parameter node.
                        Vertex paraOutVertex = addVertex(paraOutNode);
                        actualOutParameters[formalArgs[i]].push_back(paraOutVertex);
                        callInfo.outPara.push_back(paraOutVertex);

                        // Add a CD edge from call node to this actual-out node.
                        addTrueCDEdge(sdgVertex, paraOutVertex);
                    }
                }

                if (!isSgTypeVoid(funcDecl->get_type()->get_return_type())) 
                {
                    // If this function returns a value, create a actual-out vertex.
                    SDGNode* paraOutNode = new SDGNode(SDGNode::ActualOut);
                    paraOutNode->astNode = funcCallExpr;

                    // Add an actual-out parameter node.
                    Vertex paraOutVertex = addVertex(paraOutNode);
                    actualOutParameters[funcDecl].push_back(paraOutVertex);
                    callInfo.outPara.push_back(paraOutVertex);
                    callInfo.isVoid = false;
                    callInfo.returned = paraOutVertex;

                    // Add a CD edge from call node to this actual-out node.
                    addTrueCDEdge(sdgVertex, paraOutVertex);
                }

                functionCalls.push_back(callInfo);
                //funcCallToArgs[funcCallExpr] = argsNodes;
            }
        }

        // Add control dependence edges.
        addControlDependenceEdges(cfgVerticesToSdgVertices, *cfg, entryVertex);
    }
Пример #5
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
   {
#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     SgGlobal* globalScope = TransformationSupport::getGlobalScope(funcall);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

     SgExpression* funname = funcall->get_function();
     SgExpression* funname2 = isSgFunctionRefExp(funname);
     SgDotExp* dotexp = isSgDotExp(funname);
     SgArrowExp* arrowexp = isSgArrowExp(funname);
     SgExpression* thisptr = 0;
     if (dotexp || arrowexp)
        {
          funname2 = isSgBinaryOp(funname)->get_rhs_operand();
          if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
              SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
              ROSE_ASSERT (isSgInitializer(ai->get_operand()));
#if 1
              printf ("ai = %p ai->isTransformation() = %s \n",ai,ai->isTransformation() ? "true" : "false");
#endif
              SgInitializedName* in = isSgInitializedName(ai->get_parent());
              ROSE_ASSERT (in);
              removeRedundantCopyInConstruction(in);
              lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
          } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
          } else {
            assert (false);
          }
        }

     if (!funname2)
        {
       // std::cout << "Inline failed: not a call to a named function" << std::endl;
          return false; // Probably a call through a fun ptr
        }

     SgFunctionSymbol* funsym = 0;
     if (isSgFunctionRefExp(funname2))
          funsym = isSgFunctionRefExp(funname2)->get_symbol();
       else
          if (isSgMemberFunctionRefExp(funname2))
               funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
            else
               assert (false);

     assert (funsym);
     if (isSgMemberFunctionSymbol(funsym) &&
         isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
        {
       // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
          return false;
        }

     SgFunctionDeclaration* fundecl = funsym->get_declaration();
     fundecl = fundecl ? isSgFunctionDeclaration(fundecl->get_definingDeclaration()) : NULL;

     SgFunctionDefinition* fundef = fundecl ? fundecl->get_definition() : NULL;
     if (!fundef)
        {
       // std::cout << "Inline failed: no definition is visible" << std::endl;
          return false; // No definition of the function is visible
        }
     if (!allowRecursion)
        {
          SgNode* my_fundef = funcall;
          while (my_fundef && !isSgFunctionDefinition(my_fundef))
             {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
               my_fundef = my_fundef->get_parent();
               ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
             }
       // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
          assert (isSgFunctionDefinition(my_fundef));
          if (isSgFunctionDefinition(my_fundef) == fundef)
             {
               std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
               return false;
             }
        }

     SgVariableDeclaration* thisdecl = 0;
     SgName thisname("this__");
     thisname << ++gensym_counter;
     SgInitializedName* thisinitname = 0;
     if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
        {
          assert (thisptr != NULL);
          SgType* thisptrtype = thisptr->get_type();
          const SgSpecialFunctionModifier& specialMod = 
            funsym->get_declaration()->get_specialFunctionModifier();
          if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
          }
          SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
       // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
          thisptrtype = new SgModifierType(thisptrtype);
          isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
       // }
       // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
          SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
          assignInitializer->set_endOfConstruct(SgNULL_FILE);
#if 1
          printf ("before new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
#if 1
          printf ("(after new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl->set_endOfConstruct(SgNULL_FILE);
          thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
          thisdecl->set_definingDeclaration(thisdecl);

          thisinitname = (thisdecl->get_variables()).back();
          //thisinitname = lastElementOfContainer(thisdecl->get_variables());
          // thisinitname->set_endOfConstruct(SgNULL_FILE);
          assignInitializer->set_parent(thisinitname);
          markAsTransformation(assignInitializer);

       // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

       // DQ (6/23/2006): New test
          ROSE_ASSERT(assignInitializer->get_parent() != NULL);
        }

     // Get the list of actual argument expressions from the function call, which we'll later use to initialize new local
     // variables in the inlined code.  We need to detach the actual arguments from the AST here since we'll be reattaching
     // them below (otherwise we would violate the invariant that the AST is a tree).
     SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);
     SgExpressionPtrList funargs = funcall->get_args()->get_expressions();
     funcall->get_args()->get_expressions().clear();
     BOOST_FOREACH (SgExpression *actual, funargs)
         actual->set_parent(NULL);

     // Make a copy of the to-be-inlined function so we're not modifying and (re)inserting the original.
     SgBasicBlock* funbody_raw = fundef->get_body();
     SgInitializedNamePtrList& params = fundecl->get_args();
     std::vector<SgInitializedName*> inits;
     SgTreeCopy tc;
     SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
     ROSE_ASSERT (function_copy);
     SgBasicBlock* funbody_copy = function_copy->get_body();

     renameLabels(funbody_copy, targetFunction);
     ASSERT_require(funbody_raw->get_symbol_table()->size() == funbody_copy->get_symbol_table()->size());

     // We don't need to keep the copied SgFunctionDefinition now that the labels in it have been moved to the target function
     // (having it in the memory pool confuses the AST tests), but we must not delete the formal argument list or the body
     // because we need them below.
     if (function_copy->get_declaration()) {
         ASSERT_require(function_copy->get_declaration()->get_parent() == function_copy);
         function_copy->get_declaration()->set_parent(NULL);
         function_copy->set_declaration(NULL);
     }
     if (function_copy->get_body()) {
         ASSERT_require(function_copy->get_body()->get_parent() == function_copy);
         function_copy->get_body()->set_parent(NULL);
         function_copy->set_body(NULL);
     }
     delete function_copy;
     function_copy = NULL;
#if 0
     SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
     pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaBegin->set_parent(pragmaBeginDecl);
     pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
     funbody_copy->prepend_statement(pragmaBeginDecl);
     pragmaBeginDecl->set_parent(funbody_copy);
#endif

     // In the to-be-inserted function body, create new local variables with distinct non-conflicting names, one per formal
     // argument and having the same type as the formal argument. Initialize those new local variables with the actual
     // arguments.  Also, build a paramMap that maps each formal argument (SgInitializedName) to its corresponding new local
     // variable (SgVariableSymbol).
     ReplaceParameterUseVisitor::paramMapType paramMap;
     SgInitializedNamePtrList::iterator formalIter = params.begin();
     SgExpressionPtrList::iterator actualIter = funargs.begin();
     for (size_t argNumber=0;
          formalIter != params.end() && actualIter != funargs.end();
          ++argNumber, ++formalIter, ++actualIter) {
         SgInitializedName *formalArg = *formalIter;
         SgExpression *actualArg = *actualIter;

         // Build the new local variable.
         // FIXME[Robb P. Matzke 2014-12-12]: we need a better way to generate a non-conflicting local variable name
         SgAssignInitializer* initializer = new SgAssignInitializer(SgNULL_FILE, actualArg, formalArg->get_type());
         ASSERT_not_null(initializer);
         initializer->set_endOfConstruct(SgNULL_FILE);
#if 1
         printf ("initializer = %p initializer->isTransformation() = %s \n",initializer,initializer->isTransformation() ? "true" : "false");
#endif
         SgName shadow_name(formalArg->get_name());
         shadow_name << "__" << ++gensym_counter;
         SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE, shadow_name, formalArg->get_type(), initializer);
         vardecl->set_definingDeclaration(vardecl);
         vardecl->set_endOfConstruct(SgNULL_FILE);
         vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
         vardecl->set_parent(funbody_copy);

         // Insert the new local variable into the (near) beginning of the to-be-inserted function body.  We insert them in the
         // order their corresponding actuals/formals appear, although the C++ standard does not require this order of
         // evaluation.
         SgInitializedName* init = vardecl->get_variables().back();
         inits.push_back(init);
         initializer->set_parent(init);
         init->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + argNumber, vardecl);
         SgVariableSymbol* sym = new SgVariableSymbol(init);
         paramMap[formalArg] = sym;
         funbody_copy->insert_symbol(shadow_name, sym);
         sym->set_parent(funbody_copy->get_symbol_table());
     }

     // Similarly for "this". We create a local variable in the to-be-inserted function body that will be initialized with the
     // caller's "this".
     if (thisdecl) {
         thisdecl->set_parent(funbody_copy);
         thisinitname->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
         SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
         funbody_copy->insert_symbol(thisname, thisSym);
         thisSym->set_parent(funbody_copy->get_symbol_table());
         ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
     }
     ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

     SgName end_of_inline_name = "rose_inline_end__";
     end_of_inline_name << ++gensym_counter;
     SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
     end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
     printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

  // Need to set the parent of funbody_copy to avoid error.
     funbody_copy->set_parent(funbody_raw->get_parent());

     printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

     printf ("funbody_raw->get_statements().size()  = %" PRIuPTR " \n",funbody_raw->get_statements().size());
     printf ("funbody_copy->get_statements().size() = %" PRIuPTR " \n",funbody_copy->get_statements().size());

     printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
     printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

     printf ("Output the symbol table for funbody_raw \n");
     funbody_raw->get_symbol_table()->print("debugging copy problem");

  // printf ("Output the symbol table for funbody_copy \n");
  // funbody_copy->get_symbol_table()->print("debugging copy problem");

     SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
     ROSE_ASSERT(project_copy != NULL);

     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
     generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

     funbody_copy->append_statement(end_of_inline_label);
     end_of_inline_label->set_scope(targetFunction);
     SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
     end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
     targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);

     // To ensure that there is some statement after the label
     SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
     dummyStatement->set_endOfConstruct(SgNULL_FILE);
     funbody_copy->append_statement(dummyStatement);
     dummyStatement->set_parent(funbody_copy);
#if 0
     SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
     pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaEnd->set_parent(pragmaEndDecl);
     pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
     funbody_copy->append_statement(pragmaEndDecl);
     pragmaEndDecl->set_parent(funbody_copy);
#endif

     ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
     replaceExpressionWithStatement(funcall, &previsitor);

     // Make sure the AST is consistent. To save time, we'll just fix things that we know can go wrong. For instance, the
     // SgAsmExpression.p_lvalue data member is required to be true for certain operators and is set to false in other
     // situations. Since we've introduced new expressions into the AST we need to adjust their p_lvalue according to the
     // operators where they were inserted.
     markLhsValues(targetFunction);
#ifdef NDEBUG
     AstTests::runAllTests(SageInterface::getProject());
#endif

#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

  // DQ (4/7/2015): This fixes something I was required to fix over the weekend and which is fixed more directly, I think.
  // Mark the things we insert as being transformations so they get inserted into the output by backend()
     markAsTransformation(funbody_copy);

     return true;
   }
Пример #6
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
{
    SgExpression* funname = funcall->get_function();
    SgExpression* funname2 = isSgFunctionRefExp(funname);
    SgDotExp* dotexp = isSgDotExp(funname);
    SgArrowExp* arrowexp = isSgArrowExp(funname);
    SgExpression* thisptr = 0;
    if (dotexp || arrowexp)
    {
        funname2 = isSgBinaryOp(funname)->get_rhs_operand();
        if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
                SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
                ROSE_ASSERT (isSgInitializer(ai->get_operand()));
                SgInitializedName* in = isSgInitializedName(ai->get_parent());
                ROSE_ASSERT (in);
                removeRedundantCopyInConstruction(in);
                lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
        } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
        } else {
            assert (false);
        }
    }

    if (!funname2)
    {
        // std::cout << "Inline failed: not a call to a named function" << std::endl;
        return false; // Probably a call through a fun ptr
    }

    SgFunctionSymbol* funsym = 0;
    if (isSgFunctionRefExp(funname2))
        funsym = isSgFunctionRefExp(funname2)->get_symbol();
    else if (isSgMemberFunctionRefExp(funname2))
        funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
    else
        assert (false);

    assert (funsym);
    if (isSgMemberFunctionSymbol(funsym) && isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
    {
        // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
        return false;
    }

    SgFunctionDeclaration* fundecl = funsym->get_declaration();
    SgFunctionDefinition* fundef = fundecl->get_definition();
    if (!fundef)
    {
        // std::cout << "Inline failed: no definition is visible" << std::endl;
        return false; // No definition of the function is visible
    }
    if (!allowRecursion)
    {
        SgNode* my_fundef = funcall;
        while (my_fundef && !isSgFunctionDefinition(my_fundef))
        {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
            my_fundef = my_fundef->get_parent();
            ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        }
        // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        assert (isSgFunctionDefinition(my_fundef));
        if (isSgFunctionDefinition(my_fundef) == fundef)
        {
            std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
            return false;
        }
    }

    SgVariableDeclaration* thisdecl = 0;
    SgName thisname("this__");
    thisname << ++gensym_counter;
    SgInitializedName* thisinitname = 0;
    if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
    {
        assert (thisptr != NULL);
        SgType* thisptrtype = thisptr->get_type();
        const SgSpecialFunctionModifier& specialMod =
            funsym->get_declaration()->get_specialFunctionModifier();
        if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
        }
        SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
        // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
        thisptrtype = new SgModifierType(thisptrtype);
        isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
        // }
        // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
        SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
        assignInitializer->set_endOfConstruct(SgNULL_FILE);
        // thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, new SgAssignInitializer(SgNULL_FILE, thisptr));
        thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
        thisdecl->set_endOfConstruct(SgNULL_FILE);
        thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
        thisdecl->set_definingDeclaration(thisdecl);

        thisinitname = (thisdecl->get_variables()).back();
        //thisinitname = lastElementOfContainer(thisdecl->get_variables());
        // thisinitname->set_endOfConstruct(SgNULL_FILE);
        assignInitializer->set_parent(thisinitname);

        // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

        // DQ (6/23/2006): New test
        ROSE_ASSERT(assignInitializer->get_parent() != NULL);
    }

    std::cout << "Trying to inline function " << fundecl->get_name().str() << std::endl;
    SgBasicBlock* funbody_raw = fundef->get_body();
    SgInitializedNamePtrList& params = fundecl->get_args();
    SgInitializedNamePtrList::iterator i;
    SgExpressionPtrList& funargs = funcall->get_args()->get_expressions();
    SgExpressionPtrList::iterator j;
    //int ctr; // unused variable, Liao
    std::vector<SgInitializedName*> inits;
    SgTreeCopy tc;
    SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
    ROSE_ASSERT (function_copy);
    SgBasicBlock* funbody_copy = function_copy->get_body();


    SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);

    renameLabels(funbody_copy, targetFunction);
    std::cout << "Original symbol count: " << funbody_raw->get_symbol_table()->size() << std::endl;
    std::cout << "Copied symbol count: " << funbody_copy->get_symbol_table()->size() << std::endl;
    // std::cout << "Original symbol count f: " << fundef->get_symbol_table()->size() << std::endl;
    // std::cout << "Copied symbol count f: " << function_copy->get_symbol_table()->size() << std::endl;
    // We don't need to keep the copied function definition now that the
    // labels in it have been moved to the target function.  Having it in the
    // memory pool confuses the AST tests.
    function_copy->set_declaration(NULL);
    function_copy->set_body(NULL);
    delete function_copy;
    function_copy = NULL;
#if 0
    SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
    pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaBegin->set_parent(pragmaBeginDecl);
    pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
    funbody_copy->prepend_statement(pragmaBeginDecl);
    pragmaBeginDecl->set_parent(funbody_copy);
#endif
    ReplaceParameterUseVisitor::paramMapType paramMap;
    for (i = params.begin(), j = funargs.begin(); i != params.end() && j != funargs.end(); ++i, ++j)
    {
        SgAssignInitializer* ai = new SgAssignInitializer(SgNULL_FILE, *j, (*i)->get_type());
        ROSE_ASSERT(ai != NULL);
        ai->set_endOfConstruct(SgNULL_FILE);
        SgName shadow_name((*i)->get_name());
        shadow_name << "__" << ++gensym_counter;
        SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE,shadow_name,(*i)->get_type(),ai);
        vardecl->set_definingDeclaration(vardecl);
        vardecl->set_endOfConstruct(SgNULL_FILE);
        vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);

        printf ("Built new SgVariableDeclaration #2 = %p = %s initializer = %p \n",vardecl,shadow_name.str(),(*(vardecl->get_variables().begin()))->get_initializer());

        vardecl->set_parent(funbody_copy);
        SgInitializedName* init = (vardecl->get_variables()).back();
        // init->set_endOfConstruct(SgNULL_FILE);
        inits.push_back(init);
        ai->set_parent(init);
        init->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + (i - params.begin()), vardecl);
        SgVariableSymbol* sym = new SgVariableSymbol(init);
        paramMap[*i] = sym;
        funbody_copy->insert_symbol(shadow_name, sym);
        sym->set_parent(funbody_copy->get_symbol_table());
    }

    if (thisdecl)
    {
        thisdecl->set_parent(funbody_copy);
        thisinitname->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
        SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
        funbody_copy->insert_symbol(thisname, thisSym);
        thisSym->set_parent(funbody_copy->get_symbol_table());
        ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
    }
    ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

    SgName end_of_inline_name = "rose_inline_end__";
    end_of_inline_name << ++gensym_counter;
    SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
    end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
    printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

    // Need to set the parent of funbody_copy to avoid error.
    funbody_copy->set_parent(funbody_raw->get_parent());

    printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

    printf ("funbody_raw->get_statements().size()  = %zu \n",funbody_raw->get_statements().size());
    printf ("funbody_copy->get_statements().size() = %zu \n",funbody_copy->get_statements().size());

    printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
    printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

    printf ("Output the symbol table for funbody_raw \n");
    funbody_raw->get_symbol_table()->print("debugging copy problem");

    // printf ("Output the symbol table for funbody_copy \n");
    // funbody_copy->get_symbol_table()->print("debugging copy problem");

    SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
    ROSE_ASSERT(project_copy != NULL);

    const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
    generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

    // printf ("Exiting as a test after testing the symbol table \n");
    // ROSE_ASSERT(false);

    funbody_copy->append_statement(end_of_inline_label);
    end_of_inline_label->set_scope(targetFunction);
    SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
    end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
    targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);
    // To ensure that there is some statement after the label
    SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
    dummyStatement->set_endOfConstruct(SgNULL_FILE);
    funbody_copy->append_statement(dummyStatement);
    dummyStatement->set_parent(funbody_copy);
#if 0
    SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
    pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaEnd->set_parent(pragmaEndDecl);
    pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
    funbody_copy->append_statement(pragmaEndDecl);
    pragmaEndDecl->set_parent(funbody_copy);
#endif
    // std::cout << "funbody_copy is " << funbody_copy->unparseToString() << std::endl;

    ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
    // std::cout << "funbody_copy 2 is " << funbody_copy->unparseToString() << std::endl;
    replaceExpressionWithStatement(funcall, &previsitor);
    // std::cout << "Inline succeeded " << funcall->get_parent()->unparseToString() << std::endl;
    return true;
}
Пример #7
0
ATerm convertNodeToAterm(SgNode* n) 
   {
     if (n == NULL)
        {
#if 0
          printf ("convertNodeToAterm(): n = %p = %s \n",n,"NULL");
#endif
          return ATmake("NULL");
        }

     ROSE_ASSERT(n != NULL);
#if 0
     printf ("convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif

     ATerm term;
     switch (n->variantT())
        {
       // case V_SgFile:
          case V_SgSourceFile:
            // Special case needed to include file name
            // term = ATmake("File(<str>, <term>)", isSgFile(n)->getFileName(), convertNodeToAterm(isSgFile(n)->get_root()));
               term = ATmake("File(<str>, <term>)", isSgSourceFile(n)->getFileName().c_str(), convertNodeToAterm(isSgSourceFile(n)->get_globalScope()));
               break;

          case V_SgPlusPlusOp:
          case V_SgMinusMinusOp:
            // Special cases needed to include prefix/postfix status
               term = ATmake("<appl(<appl>, <term>)>",
                  getShortVariantName((VariantT)(n->variantT())).c_str(),
                  (isSgUnaryOp(n)->get_mode() == SgUnaryOp::prefix ? "Prefix" :
                   isSgUnaryOp(n)->get_mode() == SgUnaryOp::postfix ? "Postfix" :
                   "Unknown"),
                   convertNodeToAterm(isSgUnaryOp(n)->get_operand()));
               break;

          case V_SgExpressionRoot:
            // Special case to remove this node
               term = convertNodeToAterm(isSgExpressionRoot(n)->get_operand());
               break;

    case V_SgCastExp:
    // Special case needed to include type
    term = ATmake("Cast(<term>, <term>)>",
	    convertNodeToAterm(isSgUnaryOp(n)->get_operand()),
	    convertNodeToAterm(isSgCastExp(n)->get_type()));
    break;

    case V_SgVarRefExp:
    // Special case needed to include id
    term = ATmake("Var(<str>)", 
		  uniqueId(isSgVarRefExp(n)->get_symbol()->get_declaration()).c_str());
    break;

    case V_SgFunctionRefExp:
    // Special case needed to include id
    term = ATmake(
                  "Func(<str>)", 
                  uniqueId(isSgFunctionRefExp(n)->get_symbol()->get_declaration()).c_str());
    break;

    case V_SgIntVal:
    // Special case needed to include value
    term = ATmake("IntC(<int>)", isSgIntVal(n)->get_value());
    break;

    case V_SgUnsignedIntVal:
    term = ATmake("UnsignedIntC(<int>)", isSgUnsignedIntVal(n)->get_value());
    break;

    case V_SgUnsignedLongVal: {
      ostringstream s;
      s << isSgUnsignedLongVal(n)->get_value();
      term = ATmake("UnsignedLongC(<str>)", s.str().c_str());
    }
    break;

    case V_SgUnsignedLongLongIntVal: {
      ostringstream s;
      s << isSgUnsignedLongLongIntVal(n)->get_value();
      term = ATmake("UnsignedLongLongC(<str>)", s.str().c_str());
    }
    break;

    case V_SgDoubleVal:
    term = ATmake("DoubleC(<real>)", isSgDoubleVal(n)->get_value());
    break;

          case V_SgInitializedName:
             {
            // Works around double initname problem
               SgInitializer* initializer = isSgInitializedName(n)->get_initializer();
               const SgName& name = isSgInitializedName(n)->get_name();
               SgType* type = isSgInitializedName(n)->get_type();

               ROSE_ASSERT(type != NULL);
#if 0
               printf ("convertNodeToAterm(): case V_SgInitializedName: name = %s initializer = %p type = %p = %s \n",name.str(),initializer,type,type->class_name().c_str());
#endif
            // Works around fact that ... is not really an initname and shouldn't be a type either
               if (isSgTypeEllipse(type))
                  {
                    term = ATmake("Ellipses");
                  }
                 else
                  {
                    std::string uniqueIdString = uniqueId(n);
#if 0
                    printf ("uniqueIdString = %s \n",uniqueIdString.c_str());
                    printf ("Calling generate ATerm for SgInitializedName->get_name() name = %s \n",name.str());
                    ATerm name_aterm = ATmake("Name(<str>)",name.str());
                 // ATerm name_aterm = ATmake(name.str());
                    printf ("Calling convertNodeToAterm(type) \n");
                    ATerm type_aterm = convertNodeToAterm(type);
                    printf ("Calling convertNodeToAterm(initializer) \n");
#endif
                    ATerm initializer_aterm = convertNodeToAterm(initializer);
#if 0
                    printf ("Calling ATmake() \n");
#endif
#if 1
                    term = ATmake("InitName(<str>, <term>, <term>) {[id, <str>]}", 
                                    (name.str() ? name.str() : ""), 
                                    convertNodeToAterm(type), 
                                    convertNodeToAterm(initializer),
                                    uniqueId(n).c_str());
                                 // uniqueIdString.c_str());
#else
                    term = ATmake("InitName(<term>,<term>)",
                                  //(name.str() ? name.str() : ""), 
                                  // name_aterm,
                                    type_aterm, 
                                    initializer_aterm
                                 // uniqueId(n).c_str());
                                 // uniqueIdString.c_str());
                                    );
#endif
#if 0
                    printf ("Calling ATsetAnnotation() \n");
#endif
                    term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str()));
#if 0
                    printf ("DONE: Calling ATsetAnnotation() \n");
#endif
                  }

               break;
             }

    case V_SgFunctionDeclaration: {
      // Special case needed to include name
      SgFunctionDeclaration* fd = isSgFunctionDeclaration(n);
      term = ATmake("Function(<str>, <term>, <term>, <term>)", 
		    fd->get_name().str(), 
		    convertNodeToAterm(fd->get_orig_return_type()),
		    convertSgNodeRangeToAterm(fd->get_args().begin(),
					      fd->get_args().end()),
		    convertNodeToAterm(fd->get_definition()));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgClassDeclaration: {
      // Special case needed to distinguish forward/full definitions and to
      // include class name
      SgClassDeclaration* decl = isSgClassDeclaration(n);
      assert (decl);
      SgName sname = decl->get_name();
      const char* name = sname.str();
      // Suggestion: have a field named local_definition in each class
      // declaration that is 0 whenever the current declaration doesn't
      // have a definition attached, even if there is another declaration
      // which does have a definition attached.
      SgClassDefinition* defn = decl->get_definition();
      // cout << "defn = 0x" << hex << defn << endl << dec;
      if (decl->isForward())
	defn = 0;
      if (defn)
	term = ATmake("Class(<str>, <term>)", 
		      (name ? name : ""), // Will be simpler when SgName
		      // becomes string
		      convertNodeToAterm(defn));
      else
	term = ATmake("ClassFwd(<str>)", (name ? name : ""));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgEnumDeclaration: {
      // Special case to include enum name and enumerator names which are not
      // traversal children
      SgName sname = isSgEnumDeclaration(n)->get_name();
      const char* name = sname.str();
      const SgInitializedNamePtrList& enumerators = 
	isSgEnumDeclaration(n)->get_enumerators();
      term = ATmake("Enum(<str>, <term>)",
		    (name ? name : "{anonymous}"), 
		    convertSgNodeRangeToAterm(enumerators.begin(),
					      enumerators.end()));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgPointerType: {
      // Special case because types can't be traversed yet
      SgType* type = isSgPointerType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Pointer(<term>)", t);
    }
    break;

    case V_SgReferenceType: {
      // Special case because types can't be traversed yet
      SgType* type = isSgReferenceType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Reference(<term>)", t);
    }
    break;

    case V_SgModifierType: {
      // Special case for type traversal and to prettify modifier names
      SgType* type = isSgModifierType(n)->get_base_type();
      SgTypeModifier& modifier = isSgModifierType(n)->get_typeModifier();
      SgConstVolatileModifier& cvmod = modifier.get_constVolatileModifier();
      term = convertNodeToAterm(type);
      if (cvmod.isConst())
	term = ATmake("Const(<term>)", term);
      if (cvmod.isVolatile())
	term = ATmake("Volatile(<term>)", term);
    }
    break;

    case V_SgArrayType: {
      // Special case because types can't be traversed yet, and to get length
      SgType* type = isSgArrayType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Array(<term>, <term>)", t, (isSgArrayType(n)->get_index() ? convertNodeToAterm((n->get_traversalSuccessorContainer())[4]) : ATmake("<str>", "NULL")));
      assert (term);
    }
    break;

    case V_SgFunctionType: {
      // Special case to allow argument list to be traversed
      SgFunctionType* ft = isSgFunctionType(n);
      ATerm ret = convertNodeToAterm(ft->get_return_type());
      ATerm args_list = convertSgNodeRangeToAterm(ft->get_arguments().begin(),
						  ft->get_arguments().end());
      term = ATmake("FunctionType(<term>, <term>)", ret, args_list);
    }
    break;

    case V_SgEnumType:
    case V_SgClassType: 
    case V_SgTypedefType: {
      // Special cases to optionally put in type definition instead of
      // reference
      SgNamedType* nt = isSgNamedType(n);
      assert (nt);
      SgName sname = nt->get_name();
   // char* name = sname.str();
      SgDeclarationStatement* decl = nt->get_declaration();
      assert (decl);
      SgClassDefinition* defn = isSgClassDeclaration(decl) ?
				isSgClassDeclaration(decl)->get_definition() :
				0;
      term = ATmake("Type(<term>)",
		    (nt->get_autonomous_declaration() || !defn ? 
                     ATmake("id(<str>)", uniqueId(decl).c_str()) :
		     convertNodeToAterm(nt->get_declaration())));
    }
    break;

    case V_SgLabelStatement: {
      // Special case to put in label id
      const char* name = isSgLabelStatement(n)->get_name().str();
      term = ATmake("Label(<str>)", (name ? name : ""));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgGotoStatement: {
      // Special case to put in label id
      term = ATmake("Goto(<str>)", 
                    uniqueId(isSgGotoStatement(n)->get_label()).c_str());
    }
    break;

    case V_SgTypedefDeclaration: {
      // Special case to put in typedef name
      const SgName& name = isSgTypedefDeclaration(n)->get_name();
      SgType* type = isSgTypedefDeclaration(n)->get_base_type();
      term = ATmake("Typedef(<str>, <term>)", (name.str() ? name.str() : ""), 
		      convertNodeToAterm(type));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgTemplateDeclaration: {
      // Traversal doesn't work for these
      SgTemplateDeclaration* td = isSgTemplateDeclaration(n);
      ROSE_ASSERT (td);
   // SgTemplateParameterPtrListPtr paramsPtr = td->get_templateParameters();
   // SgTemplateParameterPtrList & paramsPtr = td->get_templateParameters();
   // SgTemplateParameterPtrList params =	paramsPtr ? *paramsPtr : SgTemplateParameterPtrList();
      SgTemplateParameterPtrList & params =	td->get_templateParameters();
      string templateKindString;
      switch (td->get_template_kind()) {
	case SgTemplateDeclaration::e_template_none:
	  templateKindString = "None"; break;
	case SgTemplateDeclaration::e_template_class:
	  templateKindString = "Class"; break;
	case SgTemplateDeclaration::e_template_m_class:
	  templateKindString = "MemberClass"; break;
	case SgTemplateDeclaration::e_template_function:
	  templateKindString = "Function"; break;
	case SgTemplateDeclaration::e_template_m_function:
	  templateKindString = "MemberFunction"; break;
	case SgTemplateDeclaration::e_template_m_data:
	  templateKindString = "MemberData"; break;
	default: templateKindString = "Unknown"; break;
      }
      term = ATmake("TemplateDeclaration(<appl>, <str>, <term>, <str>)",
		    templateKindString.c_str(),
		    td->get_name().str(),
		    convertSgNodeRangeToAterm(params.begin(), params.end()),
		    td->get_string().str());
    }
    break;

    case V_SgTemplateInstantiationDecl: {
      // Traversal doesn't work for these
      SgTemplateInstantiationDecl* td = isSgTemplateInstantiationDecl(n);
      ROSE_ASSERT (td);
   // SgTemplateArgumentPtrListPtr argsPtr = td->get_templateArguments();
   // SgTemplateArgumentPtrList args = argsPtr ? *argsPtr : SgTemplateArgumentPtrList();
      SgTemplateArgumentPtrList & args = td->get_templateArguments();
      term = ATmake("TemplateInstantiationDecl(<str>, <term>)", td->get_templateDeclaration()->get_name().str(), convertSgNodeRangeToAterm(args.begin(), args.end()));
    }
    break;

    case V_SgTemplateParameter: {
      // Traversal doesn't work for these
      SgTemplateParameter* tp = isSgTemplateParameter(n);
      ROSE_ASSERT (tp);
      switch (tp->get_parameterType()) {
	case SgTemplateParameter::parameter_undefined: {
	  term = ATmake("Undefined");
	}
	break;

	case SgTemplateParameter::type_parameter: {
	  term = ATmake("Type(<term>)",
			convertNodeToAterm(tp->get_defaultTypeParameter()));
	}
	break;

	case SgTemplateParameter::nontype_parameter: {
	  term = ATmake("Nontype(<term>, <term>)",
			convertNodeToAterm(tp->get_type()),
			convertNodeToAterm(tp->get_defaultExpressionParameter()));
	}
	break;

	case SgTemplateParameter::template_parameter: {
	  term = ATmake("Template");
	}
	break;

	default: term = ATmake("Unknown"); break;
      }
    }
    break;

    case V_SgTemplateArgument: {
      // Traversal doesn't work for these
      SgTemplateArgument* ta = isSgTemplateArgument(n);
      ROSE_ASSERT (ta);
      switch (ta->get_argumentType()) {
	case SgTemplateArgument::argument_undefined:
	  term = ATmake("Undefined");
	  break;
	case SgTemplateArgument::type_argument:
	  term = ATmake("Type(<term>)", 
			convertNodeToAterm(ta->get_type()));
	  break;
	case SgTemplateArgument::nontype_argument:
	  term = ATmake("Nontype(<term>)", 
			convertNodeToAterm(ta->get_expression()));
	  break;
	// case SgTemplateArgument::template_argument:
	  // term = ATmake("Template");
	  // break;
	default: term = ATmake("Unknown"); break;
      }
    }
    break;

    default: {
      bool isContainer = 
	(AstTests::numSuccContainers(n) == 1) ||
	(!isSgType(n) && (n->get_traversalSuccessorContainer().size() == 0));
      term = ATmake((isContainer ? "<appl(<term>)>" : "<appl(<list>)>"), 
                    getShortVariantName((VariantT)(n->variantT())).c_str(),
                    (isSgType(n) ? ATmake("[]") : getTraversalChildrenAsAterm(n)));
               // Special case for types is because of traversal problems
    }
    break;
  }

#if 0
     printf ("Base of switch statement in convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif
     assert (term);

     term = ATsetAnnotation(term, ATmake("ptr"), pointerAsAterm(n));

#if 1
     if (n->get_file_info() != NULL)
        {
          term = ATsetAnnotation(term, ATmake("location"),convertFileInfoToAterm(n->get_file_info()));
        }

     if (isSgExpression(n))
        term = ATsetAnnotation(term, ATmake("type"), convertNodeToAterm(isSgExpression(n)->get_type()));
#endif

#if 0
     printf ("Leaving convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif
#if 0
     printf ("--- n->class_name() = %s ATwriteToString(term) = %s \n",n->class_name().c_str(),ATwriteToString(term));
#endif

  // cout << n->sage_class_name() << " -> " << ATwriteToString(term) << endl;
     return term;
   }
Пример #8
0
NameQuerySynthesizedAttributeType
NameQuery::queryVariableNamesWithTypeName (SgNode * astNode, string matchingName)
{

  ROSE_ASSERT (astNode != 0);
  ROSE_ASSERT (matchingName.length () > 0);

  NameQuerySynthesizedAttributeType returnNameList;

// SgVarRefExp *sageVarRefExp = isSgVarRefExp (astNode);


  switch (astNode->variantT ())
    {
    case V_SgVariableDeclaration:
      {
        SgVariableDeclaration *sageVariableDeclaration =
          isSgVariableDeclaration (astNode);
        ROSE_ASSERT (sageVariableDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList =
          sageVariableDeclaration->get_variables ();

#if DEBUG_NAMEQUERY
        printf ("\nIn filename: %s ",
                ROSE::getFileName (isSgLocatedNode (astNode)));
        printf ("\nHere is a variable :Line = %d Columns = %d \n",
                ROSE::getLineNumber (isSgLocatedNode (astNode)),
                ROSE::getColumnNumber (isSgLocatedNode (astNode)));
        //cout << "The typename of the variable is: " << typeName << endl;
#endif
        SgType *typeNode;
        typedef SgInitializedNamePtrList::iterator variableIterator;

        for (variableIterator variableListElement =
             sageInitializedNameList.begin ();
             variableListElement != sageInitializedNameList.end ();
             ++variableListElement)
          {
            SgInitializedName* elmVar = *variableListElement;

            ROSE_ASSERT (elmVar != NULL);
            typeNode = elmVar->get_type ();
            ROSE_ASSERT (typeNode != NULL);
            string typeName = TransformationSupport::getTypeName(typeNode);

            if (typeName == matchingName)
              {
                string name = elmVar->get_name ().str ();
                ROSE_ASSERT (name.length () > 0);
                returnNameList.push_back (name);
#if DEBUG_NAMEQUERY
                cout << "The name of the variable is: " << name << endl;
#endif
              }
          }
        break;
      }                         /* End case V_SgVariableDeclaration */

    case V_SgFunctionDeclaration:
    case V_SgMemberFunctionDeclaration:
       {
      SgFunctionDeclaration * sageFunctionDeclaration =
        isSgFunctionDeclaration (astNode);
      ROSE_ASSERT (sageFunctionDeclaration != NULL);

      SgInitializedNamePtrList sageInitializedNameList = sageFunctionDeclaration->get_args ();

      SgType *typeNode;

      typedef SgInitializedNamePtrList::iterator variableIterator;

      for (variableIterator variableListElement =
           sageInitializedNameList.begin ();
           variableListElement != sageInitializedNameList.end ();
           ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          ROSE_ASSERT (elmVar != NULL);
          typeNode = elmVar->get_type ();
          ROSE_ASSERT (typeNode != NULL);
          string typeName = TransformationSupport::getTypeName (typeNode);

          if (typeName == matchingName)
            {
              string name = elmVar->get_name ().str ();
              ROSE_ASSERT (name.length () > 0);
              returnNameList.push_back (name);
#if DEBUG_NAMEQUERY
              cout << "The name of the variable is: " << name << endl;
#endif
            }
        }

      break;
       }

      default:
        {
       // DQ (8/20/2005): Added default to avoid compiler warnings about unrepresented cases
        }
    }                           /* End switch case astNode */

  return returnNameList;

}                               /* End function NameQuery::queryNameVariableNames() */
Пример #9
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameVariableNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

// SgVarRefExp *sageVarRefExp = isSgVarRefExp (astNode);

  switch (astNode->variantT ())
    {
      /*
         case V_SgVarRefExp:
         {
         SgVarRefExp* sageVarRefExp = isSgVarRefExp(astNode);
         ROSE_ASSERT( sageVarRefExp != NULL);

         SgVariableSymbol* variableSymbol = sageVarRefExp->get_symbol();
         ROSE_ASSERT (variableSymbol != NULL);

         SgType* type = variableSymbol->get_type();
         ROSE_ASSERT (type != NULL);


         string typeName = TransformationSupport::getTypeName(type);
         ROSE_ASSERT (typeName.length() > 0);


         // Only define the variable name if we are using an object of array type
         SgInitializedName* initializedName = variableSymbol->get_declaration();
         ROSE_ASSERT (initializedName != NULL);
         SgName variableName = initializedName->get_name();
         printf("\nIn filename: %s ", ROSE::getFileName(isSgLocatedNode(astNode)));
         printf ("\nHere is a variable :Line = %d Columns = %d \n", ROSE:: getLineNumber (isSgLocatedNode(astNode) ), ROSE:: getColumnNumber ( isSgLocatedNode(astNode) ));
         cout << "The typename of the variable is: " << typeName << endl;
         cout << "The name of the variable is: " << variableName.str() << endl;
         // copy the string to avoid corruption of the AST's version of the string
         string name = variableName.str();
         returnNameList.push_back (name);

         break;
         }
       */

    case V_SgVariableDeclaration:
      {
        SgVariableDeclaration *sageVariableDeclaration =
          isSgVariableDeclaration (astNode);
        ROSE_ASSERT (sageVariableDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables ();

#if DEBUG_NAMEQUERY
        printf ("\nIn filename: %s ",
                ROSE::getFileName (isSgLocatedNode (astNode)));
        printf ("\nHere is a variable :Line = %d Columns = %d \n",
                ROSE::getLineNumber (isSgLocatedNode (astNode)),
                ROSE::getColumnNumber (isSgLocatedNode (astNode)));
        //cout << "The typename of the variable is: " << typeName << endl;
#endif

        typedef SgInitializedNamePtrList::iterator variableIterator;

        for (variableIterator variableListElement =
             sageInitializedNameList.begin ();
             variableListElement != sageInitializedNameList.end ();
             ++variableListElement)
          {
            SgInitializedName* elmVar = *variableListElement;
            ROSE_ASSERT (elmVar != NULL);
            string name = elmVar->get_name ().str ();
            ROSE_ASSERT (name.length () > 0);
            returnNameList.push_back (name);
#if DEBUG_NAMEQUERY
            cout << "The name of the variable is: " << name << endl;
#endif
          }
        break;
      }                         /* End case V_SgVariableDeclaration */

    case V_SgFunctionDeclaration:
    case V_SgMemberFunctionDeclaration:
       {
      SgFunctionDeclaration * sageFunctionDeclaration =
        isSgFunctionDeclaration (astNode);
      ROSE_ASSERT (sageFunctionDeclaration != NULL);

      SgInitializedNamePtrList sageInitializedNameList = sageFunctionDeclaration->get_args ();


      typedef SgInitializedNamePtrList::iterator variableIterator;

      for (variableIterator variableListElement =
           sageInitializedNameList.begin ();
           variableListElement != sageInitializedNameList.end ();
           ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          ROSE_ASSERT (elmVar != NULL);
          string name = elmVar->get_name ().str ();
          ROSE_ASSERT (name.length () > 0);
          returnNameList.push_back (name);
#if 1
          cout << "The name of the variable is: " << name << endl;
#endif
        }

      break;
        }
       
      default:
        {
       // DQ (8/20/2005): Added default to avoid compiler warnings about unrepresented cases
        }
    }                           /* End switch case astNode */


  return returnNameList;

}                               /* End function queryNameVariableNames() */