Transformação básica de origem para origem com o Clang

I have successfully build the sample code

Agora eu tenho um requisito que, se eu tiver um código de exemplo como abaixo:

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

O código deve se transformar em

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

Eu tentei com as seguintes alterações no código:

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

Mas a saída vem como:

// 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

Por favor, deixe-me saber como posso alcançar o objetivo?

Eu também recebo saída como:

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;

Como posso parar o código renderizado da mesma forma? É só que as declarações no bloco composto devem adicionar instruções extras.

3
adicionado editado
Visualizações: 1
Não parece que a sua função VisitStmt retorna um valor booleano sensato, e eu suspeito que a visita depende de tal resultado booleano para decidir se deve descer em subárvores. Apenas um palpite.
adicionado o autor Ira Baxter, fonte

2 Respostas

Se você olhar para o código gerado, é uma bagunça ilegal. Uma maravilha o compilador não grita seus ouvidos ;-)

Claramente o LLVM (com seu VisitStmt) considera apenas "{...}" como "declaração composta", e a saída acontece antes da declaração em si. Verifique cuidadosamente quando essas ações intercaladas estão concluídas (suspeito que seja apenas antes ou logo depois, não no meio).

1
adicionado

Se eu entendi corretamente, e para adicionar a @vonbrand, você não deve usar o início e o fim da instrução Compound, pois eles representam o bloco de instruções. Em vez disso, você deve substituir o texto acima por inserção do texto (instruções de impressão) no corpo genérico do VisitStmt. Observe que não estou certo do que você está tentando realizar, pois você não tem uma instrução Print imediatamente após sua instrução if/else. Acho que ajudaria se você apenas listasse quais instruções deseja processar e, em seguida, teria condicionais "isa" em sua transação de implementação de visitante em cada caso. Dessa forma, você está realmente usando o padrão de visitante corretamente. Espero que ajude!

0
adicionado