ROSE 编译器框架/转换跟踪
外观
	
	
一个跟踪转换的实验性功能
转换跟踪或 IR 映射信息
- 每个 AST 节点都分配了一个唯一的整数 ID,基于 AST 的先序遍历。
- 一个转换生成的节点(受影响节点)与一个或多个输入节点相连。
- 存储在 std::map<AST_NODE_ID, std::set<AST_NODE_ID> > 中,从受影响节点映射到其输入节点集。
这是一个很少使用的功能。为了避免内存/计算开销,我们将信息存储在独立的内存中,而不是直接扩展 AST 节点的成员。
跟踪基于 AST 节点的唯一 ID。为了禁用已删除 AST 节点的内存重用,建议使用以下配置 ROSE:
- --enable-memory-pool-no-reuse 启用特殊的内存池模型:不重用已删除的内存(默认情况下重用内存)
源代码和 API 函数定义在 https://github.com/rose-compiler/rose-develop/tree/master/src/midend/programTransformation/transformationTracking
来自
//! Assign Ids and save current File Info. void registerAstSubtreeIds (SgNode* root); // get unique ID AST_NODE_ID getId (SgNode* ); // check if a node has been assigned a unique ID bool hasId (SgNode* n); //Obtain the SgNode from an ID SgNode* getNode (AST_NODE_ID id); // the input AST node IDs for a transformation generated node. extern std::map<AST_NODE_ID, std::set<AST_NODE_ID> > inputIDs; // This should be called after the transformation is completed and all IDs are assigned. void addInputNode(SgNode* affected_node, SgNode* inputnode);
来自 transformationTracking.cpp:内部两个映射/表存储 ID 和内存地址
// the following data structures are for internal use only std::map <SgNode*, unsigned int > AstToIdTable; // reverse lookup , oops, if they are one-to-one mapping, how a single node obtains multiple IDs? std::map <unsigned int, SgNode*> IdToAstTable;
// Assign portable and unique IDs for all located nodes in AST
  TransformationTracking::registerAstSubtreeIds (project);
// Dump AST dotgraph with unique IDs , for debugging purpose
 // Test unique ID assignment and dot graph generation
    TransformationTracking::registerAstSubtreeIds (sageProject);
    generateWholeGraphOfAST("wholeAST-v1");
    AstDOTGeneration astdotgen;
    astdotgen.generate(sageProject,AstDOTGeneration::TOPDOWNBOTTOMUP, "v1");
// record the input node of an affected node after some transformation
     // patch up IDs for the changed subtree 
      TransformationTracking::registerAstSubtreeIds (orig_scope);
      std::vector <SgVariableDeclaration*>::iterator iter;
      for (iter = newly_inserted_copied_decls.begin(); iter!= newly_inserted_copied_decls.end(); iter++)
      { //TransformationTracking::addInputNode (affected_node, input_node)
        TransformationTracking::addInputNode (*iter, decl);
      }
// retrieve stored mapping information
   std::map<AST_NODE_ID, std::set<AST_NODE_ID> >::iterator iter;
    for (iter = TransformationTracking::inputIDs.begin(); iter != TransformationTracking::inputIDs.end(); iter++)
    {
      std::set<AST_NODE_ID> ids = (*iter).second;
      if (ids.size()>0)
      {
        string src_comment = "Transformation generated based on ";
        cout<<"Found a node with IR mapping info"<<endl;
        SgNode* affected_node = TransformationTracking::getNode((*iter).first);
        cout<<isSgLocatedNode(affected_node)->unparseToString()<<endl;
        cout<<"-- with input nodes ----------"<<endl;
        std::set<AST_NODE_ID>::iterator iditer;
        for(iditer = ids.begin(); iditer != ids.end(); iditer ++)
        {
           SgNode* input_node = TransformationTracking::getNode((*iditer));
           SgLocatedNode* lnode = isSgLocatedNode(input_node);
           cout<<lnode->unparseToString()<<endl;
           cout<<"//Transformation generated based on line #"<< lnode->get_file_info()->get_line() <<endl;
           src_comment += " line # " + StringUtility::numberToString(lnode->get_file_info()->get_line());
        }
        src_comment +="\n";
        SgStatement* enclosing_stmt = getEnclosingStatement(affected_node);
        attachComment (enclosing_stmt, src_comment);
      } // end if ids.size() >0
    }  // end for inputIDs