【问题标题】:Assignment Insertion in ROSE compiler after AssignOpAssignOp之后ROSE编译器中的赋值插入
【发布时间】:2015-08-26 03:27:30
【问题描述】:

最近我一直在使用 ROSE 编译器,我能够将一些代码插入应用到 C 源代码中并获得成功的输出。但是,我在访问 SgAssignOps 时无法插入赋值语句。这是我的代码的简化版本,用于显示问题:

#include "rose.h"
#include <iostream>
#include <transformationSupport.h>
using namespace SageInterface;
using namespace SageBuilder;
using namespace std;

int main (int argc, char *argv[])
{
    SgProject *project = frontend (argc, argv);

    // Find all Assignment operations
    std::vector<SgNode* > assignOpList = NodeQuery::querySubTree (project, V_SgAssignOp);

    std::vector<SgNode*>::iterator iter;

    for (iter = assignOpList.begin(); iter!= assignOpList.end(); iter++) { 

        SgNode * node = (*iter);

        SgStatement * asmStmt = TransformationSupport::getStatement(node);

        //ADD PRAGMA STATEMENT BEFORE       
        ostringstream osPragma;
        osPragma << "example statement";
        SgPragmaDeclaration* pragmaDecl = buildPragmaDeclaration(osPragma.str());
        insertStatementBefore(asmStmt, pragmaDecl);

        //ADD ASSIGNMENT STATEMENT AFTER
        SgExprStatement* newAsmt = buildAssignStatement(buildVarRefExp("a"),buildIntVal(9));
        insertStatementAfter(asmStmt,newAsmt);
    }

    AstTests::runAllTests(project); 
    // Translation only
    project->unparse();
}

一个简单的输入代码:

int main(int argc, char* argv[])
{
    int a;

    a = 3;

    return a;

}

代码编译。不过..

当应用于输入代码时,我得到一个分段错误,没有错误消息。

如果我删除赋值语句插入,则 pragma 插入有效。

如果我删除对 runAllTests() 的调用,我会在解析时收到以下错误消息:

test: /mnt/DATA/rose/src/backend/unparser/nameQualificationSupport.C:4986: virtual NameQualificationInheritedAttribute NameQualificationTraversal::evaluateInheritedAttribute(SgNode*, NameQualificationInheritedAttribute): Assertion `initializedName->get_parent() != __null' failed.
Aborted (core dumped)

注意我在这个例子和输入代码中使用了“a”,所以变量已经被声明了。

这样插入作业的正确方法是什么?

本教程中提供的示例使用主函数体上的范围并将其插入到最后,我需要它在另一个赋值之后发生。我需要将节点上的 Scope 推送到 ScopeStack 吗?如果是这样,那将如何表达?我对 push 和 pop 范围堆栈方法不是很熟悉。

【问题讨论】:

    标签: c compiler-construction code-translation rose-compiler-framework


    【解决方案1】:

    这是旧的,但为将来有这个问题的人回答。

    错误实际上来自于调用 buildVarRefExp 和 buildPragmaDeclaration 时。从doxygen 可以看出,它们为 SgScopeStatement 提供了一个可选参数。这个范围声明是 SageBuilder 找到引用的变量 (github source) 的地方。 如果没有给出,它将从 ScopeStack 中获取。但是,当您没有将任何内容推送到 ScopeStack 并在没有可选参数的情况下调用这些函数时,它不知道在哪里查找。

    所以,你的两个解决方案是:

    1. 使用 ScopeStack 存储 SgScopeStatement(例如 pushScopeStack)
    2. 将 SgScopeStatement 作为参数传递给 buildVarRefExp 和 buildPragmaDeclaration。

    具体来说,你可以这样做:

    SgScopeStatement scope = TransformationSupport::getFunctionDeclaration(node)->get_scope();
    

    并将您的 SageBuilder 语句替换为:

    buildPragmaDeclaration(osPragma.str(), scope);
    buildVarRefExp("a", scope);
    

    【讨论】:

      【解决方案2】:

      好的...在写我的问题时,我意识到我必须再给范围方法一次机会。

      我发现将范围设置为函数有效,因此:

          pushScopeStack (TransformationSupport::getFunctionDeclaration(node)->get_scope());
          SgExprStatement* newAsmt = buildAssignStatement(buildVarRefExp("a"),buildIntVal(9));        
          insertStatementAfter(asmStmt,newAsmt);
          popScopeStack();
      

      我觉得这是正确的做法,但我仍然觉得缺少有关使用这些方法和一般 ScopeStack 的文档。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-25
        • 1970-01-01
        • 2012-08-18
        • 2014-11-26
        • 2014-09-20
        相关资源
        最近更新 更多