تحويل المصدر إلى المصدر الأساسي مع Clang

I have successfully build the sample code

الآن لدي مطلب بأن يكون لدي نموذج لشفرة مثل أدناه:

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(s)) {
        CompoundStmt *Statement = cast(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;

كيف يمكنني إيقاف التعليمة البرمجية التي يتم تقديمها؟ لها فقط أن البيانات في كتلة مجمع يجب إضافة بيانات إضافية.

3
لا يبدو أن الدالة VisitStmt تقوم بإرجاع قيمة منطقية معقولة ، وأظن أن الزيارة تعتمد على هذه النتيجة المنطقية لتقرير ما إذا كان يجب أن تنزل إلى أشجار فرعية. مجرد تخمين.
وأضاف المؤلف Ira Baxter, مصدر

2 إجابة

إذا نظرت إلى الشفرة التي تم إنشاؤها ، فهي فوضى غير قانونية. عجب المترجم لا تصرخ أذنيك ؛-)

بوضوح LLVM (مع VisitStmt) تعتبر فقط "{...}" كـ "بيان مركب" ، ويحدث الإخراج قبل العبارة نفسها. تحقق بعناية عند القيام بهذه الإجراءات المتخللة (أظن إما قبل أو بعد ، وليس في المنتصف).

1
وأضاف

إذا فهمت بشكل صحيح ، وأضفها إلىvonbrand ، يجب ألا تستخدم بداية البيان المركب ونهايته لأنهما يمثلان كتلة البيانات. بدلاً من ذلك ، يجب عليك استبدال ما سبق بإدخال النص (عبارات الطباعة) في نص VisitStmt العام. لاحظ أنه ليس من الواضح ما الذي تحاول إنجازه ، لأنك لا تملك بيان طباعة مباشرة بعد عبارة if/else الخاصة بك. أعتقد أنه سيساعدك إذا كنت قد أدرجت فقط البيانات التي ترغب في معالجتها ، ومن ثم لديك شروط "isa" في اتفاق تنفيذ الزائر مع كل حالة. بهذه الطريقة ، فأنت تستخدم نموذج الزائر بشكل صحيح. امل ان يساعد!

0
وأضاف