0

I would like to know how to insert an argument to a function call using libclang? I have to following code that just prints the arguments:

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;
    }
...
};

Edit:

And although I can read and set the arguments, I don't see any way to insert one at the beginning of the parmVarDcl() matcher.

The same goes with adding member variables to base classes and compound statements. It would seem you can change existing text but you cannot insert new object easily. Am I right?

  • Also: "Clang is not designed to support mutation of its AST": https://stackoverflow.com/a/10763844/7392560 I think adding a simple parameter to function calls will be more complicated than I expected. – Phil Bouchard Nov 13 '17 at 05:49

1 Answers1

0

The only solution I found so far is by getting a file pointer from a cursor and injecting code manually:

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);

If anybody has a better idea then please let me know!