在AssignOp

时间:2015-06-10 17:52:47

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

最近我一直在使用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)

注意我正在使用&#34; a&#34;在此示例和输入代码中,因此已声明变量。

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

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

2 个答案:

答案 0 :(得分:1)

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

错误实际上来自于调用buildVarRefExp和buildPragmaDeclaration时的错误。通过doxygen可以看到,它们为SgScopeStatement提供了一个可选参数。此范围语句是SageBuilder找到引用的变量(github source)的位置。 如果没有给出,则从ScopeStack 获取它。但是,当你没有将任何东西推到ScopeStack上并在没有可选参数的情况下调用这些函数时,它就不知道在哪里看。

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

  1. 使用ScopeStack存储SgScopeStatement(例如pushScopeStack)
  2. 将SgScopeStatement作为参数传递给buildVarRefExp和buildPragmaDeclaration。
  3. 具体而言,您可以这样做:

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

    用以下内容替换您的SageBuilder语句:

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

答案 1 :(得分:0)

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

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

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

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