Базовое преобразование источника в источник с помощью Clang

Я успешно собрал пример кода< /а>

Теперь у меня есть требование, чтобы, если у меня есть пример кода, как показано ниже:

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;

Как я могу остановить рендеринг кода? Просто операторы в составном блоке должны добавлять дополнительные операторы.


person Programmer    schedule 18.06.2012    source источник
comment
Не похоже, чтобы ваша функция VisitStmt возвращала разумное логическое значение, и я подозреваю, что посещение зависит от такого логического результата, чтобы решить, должно ли оно опускаться в поддеревья. Просто предположение.   -  person Ira Baxter    schedule 18.06.2012


Ответы (2)


Если вы посмотрите на сгенерированный код, это незаконный беспорядок. Удивительно, что компилятор не кричит вам уши ;-)

Ясно, что LLVM (с вашим VisitStmt) рассматривает только "{...}" как "составной оператор", и вывод происходит перед самим оператором. Внимательно проверяйте, когда совершаются такие вкрапленные действия (подозреваю, либо непосредственно перед, либо сразу после, а не в середине).

person vonbrand    schedule 20.01.2013

Если я правильно понимаю, и чтобы добавить к @vonbrand, вы не должны использовать начало и конец составного оператора, поскольку они представляют блок операторов. Вместо этого вы должны просто заменить приведенное выше вставкой текста (операторов печати) в общее тело VisitStmt. Обратите внимание, что мне неясно, чего вы пытаетесь достичь, поскольку у вас нет оператора Print сразу после оператора if/else. Я думаю, было бы полезно, если бы вы просто перечислили, какие операторы вы хотите обработать, а затем использовали условные выражения «isa» в реализации вашего посетителя для каждого случая. Таким образом, вы на самом деле правильно используете шаблон посетителя. Надеюсь, это поможет!

person R.K    schedule 04.02.2013