2017-11-11 36 views
0

我想知道如何使用libclang爲函數調用插入參數?我有下面的代碼,僅僅打印參數:如何使用libclang注入代碼(在C++中)

class CASTVisitor : public RecursiveASTVisitor<CASTVisitor> 
{ 
public: 
    CASTVisitor(Rewriter &R) : rewriter(R) 
    { 
    } 

    virtual bool VisitCallExpr(CallExpr *call) 
    { 
     for(int i = 0, j = call->getNumArgs(); i < j; ++ i) 
     { 
      errs() << "argType: " << call->getArg(i)->getType().getAsString() << "\n"; 
     } 

     errs() << "** Added parameter to function call\n"; 

     return true; 
    } 
... 
}; 

編輯:

雖然我可以讀取和設置參數,我沒有看到任何方式插入一個之初parmVarDcl()匹配器。

將基本類和複合語句添加成員變量也是一樣。您似乎可以更改現有文本,但不能輕鬆插入新對象。我對嗎?

+0

又道:「鏘並非設計用於支持其AST的突變」: https://stackoverflow.com/a/10763844/7392560 我想添加一個簡單的參數調用函數會比我預想的更復雜。 –

回答

0

我發現迄今是從遊標中獲取文件指針和手動注入代碼的唯一解決辦法:

https://github.com/burnflare/libclang-experiments

CXFile file; 
unsigned line; 
unsigned offset; 

clang_getSpellingLocation(clang_getCursorLocation(cursors[i+1]), 
          &file, 
          &line, 
          NULL, 
          &offset); 

const char* filename = clang_getCString(clang_getFileName(file)); 
printf("\n\nMethod found in %s in line %d, offset %d\n", clang_getCString(clang_getFileName(file)), line, offset); 

// File reader 
FILE *fr = fopen(filename, "r"); 
fseek(fr, 0, SEEK_END); 
long fsize = ftell(fr); 
fseek(fr, 0, SEEK_SET); 

// Reading file to string 
char *input = malloc(fsize); 
fread(input, fsize, 1, fr); 
fclose(fr); 

// Making an output that is input(start till offset) + code injection + input(offset till end) 
FILE *fw = fopen(filename, "w"); 
char *output = malloc(fsize); 
strncpy(output, input, offset); 
strcat(output, injectCode); 
strcat(output, input+offset); 

// Rewrite the whole file with output string 
fwrite(output, fsize, sizeof(output), fw); 
fclose(fw); 

如果有人有更好的主意,那麼請讓我知道!