Grundlegende Source-Source-Transformation mit Clang

I have successfully build the sample code

Jetzt habe ich eine Anforderung, dass, wenn ich einen Beispielcode wie unten habe:

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

Der Code sollte in transformiert werden

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

Ich habe es mit folgenden Codeänderungen versucht:

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

Aber die Ausgabe kommt als:

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

Bitte lassen Sie mich wissen, wie ich das Ziel erreichen kann?

Ich bekomme auch Ausgaben wie:

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;

Wie kann ich den Code-Rendering stoppen? Es ist nur so, dass die Anweisungen im zusammengesetzten Block zusätzliche Anweisungen hinzufügen sollten.

3
hinzugefügt bearbeitet
Ansichten: 1
Es sieht nicht so aus, als ob Ihre VisitStmt-Funktion einen vernünftigen booleschen Wert zurückgibt, und ich vermute, dass der Besuch von einem solchen booleschen Ergebnis abhängt, um zu entscheiden, ob er in Unterbäume absteigt. Nur eine Vermutung.
hinzugefügt der Autor Ira Baxter, Quelle

2 Antworten

Wenn Sie sich den generierten Code anschauen, handelt es sich um ein illegales Chaos. Ein Wunder, dass der Compiler deine Ohren nicht schreit ;-)

Offensichtlich betrachtet LLVM (mit Ihrem VisitStmt) nur "{...}" als "zusammengesetzte Anweisung", und die Ausgabe erfolgt vor der Anweisung selbst. Überprüfen Sie sorgfältig, wann solche eingestreuten Aktionen ausgeführt werden (ich vermute entweder kurz davor oder kurz danach, nicht in der Mitte).

1
hinzugefügt

Wenn ich es richtig verstehe und zu @vonbrand hinzufüge, sollten Sie den Anfang und das Ende der zusammengesetzten Anweisung nicht verwenden, da sie den Anweisungsblock darstellen. Stattdessen sollten Sie die obigen Anweisungen ersetzen, indem Sie den Text (Print-Anweisungen) in den generischen VisitStmt-Text einfügen. Beachten Sie, dass ich nicht genau weiß, was Sie erreichen möchten, da Sie unmittelbar nach Ihrer if/else-Anweisung keine Print-Anweisung haben. Ich denke, es würde helfen, wenn Sie nur aufgeführt haben, welche Anweisungen Sie verarbeiten möchten, und dann "isa" Bedingungen in Ihrer Besucherimplementierung mit jedem Fall haben. Auf diese Weise verwenden Sie das Besuchermuster tatsächlich korrekt. Ich hoffe, das hilft!

0
hinzugefügt