2012-06-18 90 views
3

我已经成功地建立sample code基本源到源变换铿锵

现在我的我有一个要求,如果我有一个像下面的示例代码:

int inc(int& p) 
{ 
     p++; 
     printf("In inc [%d]\n", p); 
     return p; 
} 
int main() 
{ 
     int i = 0; 
     int y,z; 
     if(y == 0) 
       print(inc(i) , inc(i)); 
     else 
     { 
       print(inc(i) , inc(i)); 
     } 
     printf("y = [%d] z = [%d]\n", y , z); 
     return 0; 
} 

代码应转换为

int inc(int& p) 
{ 
     p++; 
     printf("%s %d", __FILE__, __LINE__); 
     printf("In inc [%d]\n", p); 
     printf("%s %d", __FILE__, __LINE__); 
     return p; 
} 

int main() 
{ 
     int i = 0; 
     printf("%s %d", __FILE__, __LINE__); 
     int y,z; 
     printf("%s %d", __FILE__, __LINE__); 
     if(y == 0) 
       print(inc(i) , inc(i)); 
     else 
     { 
       print(inc(i) , inc(i)); 
       printf("%s %d", __FILE__, __LINE__); 
     } 
     printf("y = [%d] z = [%d]\n", y , z); 
     printf("%s %d", __FILE__, __LINE__); 
     return 0; 
} 

我试着用下面的代码更改:

bool VisitStmt(Stmt *s) { 
    // Only care about If statements. 
    if (isa<CompoundStmt>(s)) { 
     CompoundStmt *Statement = cast<CompoundStmt>(s); 
     TheRewriter.InsertText(Statement->getLocStart(), 
           "printf(\"%s %d\", __FILE__, __LINE__);\n", 
           true, true); 
    } 

但产量当属:

// Begin function inc returning int 
int inc(int& p) 
printf("%s %d", __FILE__, __LINE__); 
{ 
     p++; 
     printf("In inc [%d]\n", p); 
     return p; 
} 
// End function inc 

// Begin function main returning int 
int main() 
printf("%s %d", __FILE__, __LINE__); 
{ 
     int i = 0; 
     int y,z; 
     if(y == 0) 
       print(inc(i) , inc(i)); 
     else 
     { 
       print(inc(i) , inc(i)); 
     } 
     printf("y = [%d] z = [%d]\n", y , z); 
     return 0; 
} 
// End function main 

请让我知道我可以达到这个目标?

我也得到这样的输出:

test.cpp:4:26: error: use of undeclared identifier 'p' 
     printf("In inc [%d]\n", p); 
           ^
test.cpp:5:9: error: use of undeclared identifier 'p' 
     return p; 

如何停止代码渲染一样吗?只是复合块中的语句应该添加额外的语句。

+0

它看起来并不像你VisitStmt函数返回一个明智的布尔值,我怀疑来访依赖于这样的布尔结果来决定是否应该陷入子树。只是一个猜测。 –

回答

1

如果你看看生成的代码,这是一个非法的混乱。一个奇迹,编译器不会尖叫你的耳朵;-)

显然LLVM(与您的VisitStmt)认为只是“{...}”为“复合语句”,并且输出发生在语句本身之前。仔细检查这些穿插行为是否完成(我怀疑是在之前还是之后,而不是在中间)。

0

如果我理解正确并添加到@vonbrand,则不应使用复合语句的开始和结束,因为它们表示语句块。 相反,您应该在通用VisitStmt正文中插入文本(打印语句)来替换上述内容。请注意,我不清楚你想要完成什么,因为在if/else语句后没有立即打印语句。 我认为如果你刚刚列出了你想要处理的语句,然后在你的访问者实现中有“isa”条件来处理每个事件,它会有所帮助。这样,您实际上正确使用访问者模式。 希望有所帮助!