Обработка функций C ++ с помощью API Clang для вставки кода - PullRequest
9 голосов
/ 07 июля 2011

Мне нужно предварительно обработать некоторые C ++ файлы для автоматической вставки кода для тестирования и профилирования, и мне нужно сделать это с помощью clang API .

Сейчас я хочу сделать следующее: Если есть функция:

int SomeFn(int a, int b, int c) {
    doStuff();
}

Я хочу предварительно обработать его, чтобы он выглядел так:

int SomeFn(int a, int b, int c) {
    cout << "SomeFn is invoked with the following arguments: a=" << a << ", b=" << b << ", c=" << c << endl;
    doStuff();
}

Я пытался расширить ASTConsumer и использовать методы HandleTopLevelDecl и HandleTopLevelSingleDecl и проверить, являются ли переданные Decls значения FunctionDecls, и уменьшить их, чтобы я мог получить их имена и местонахождение. Но я не могу обрабатывать методы класса таким образом, только глобальные функции.

Я нашел функцию в ASTConsumer классе HandleTagDeclDefinition(TagDecl* D). В документации сказано:

Этот обратный вызов вызывается каждый раз, когда TagDecl (например, структура, объединение, перечисление, класс) завершен.

Но похоже, что этот метод даже не вызывается, когда я проверяю его.

Итак, мой вопрос: что было бы правильным способом выполнить эту задачу? И как классы C ++ представлены в Clang API? Может быть, кто-то знает, где я могу найти примеры, потому что API Clang плохо документированы.


UPDATE:

Я знаю, что есть также понятие Visitors, и есть метод VisitRecordDecl(RecordDecl *D). В документации сказано, что RecordDecl представляет классы. Поэтому я расширил RecursiveASTVisitor и внедрил VisitRecordDecl(RecordDecl *D), но кажется, что этот метод также не вызывается. Вместо этого VisitVarDecl вызывается, когда определением класса является find, как если бы оно рассматривалось как объявление переменной. Так что я немного растерялся. Я надеюсь, кто-то может помочь ...


UPDATE2:

Я попытался разобрать другой файл, и на этот раз clang нашел один RecordDecl. Но файл определил одну структуру и два класса, поэтому я думаю, что мой код Clang анализирует C вместо C ++ . Есть ли какие-либо настройки для переключения между C и C ++ ?

Ответы [ 3 ]

10 голосов
/ 09 июля 2011

Есть ли какие-нибудь настройки для переключения между C и C ++?

Наконец-то я узнал, как с этим справиться:

Я расширил с ASTConsumer и RecursiveASTVisitor<MyConsumer> пройти АСТ и внедрить VisitCXXRecordDecl(CXXRecordDecl* D).Затем мне пришлось установить параметр LangOptions для препроцессора, чтобы он анализировал C ++.

langOpts.CPlusPlus = 1;

Я ошибался, полагая, что он сразу проанализирует C ++, но это не так, он анализируетC по умолчанию и поэтому не распознает классы.

3 голосов
/ 07 июля 2011

Мне интересно, почему вы хотите сделать это преобразование на лету (если я вас правильно понял). Это особенно сложно с методами C ++, определенными в классе, так как они компилируются так, как будто они определены вне класса (то есть все члены класса могут использоваться, даже те, которые еще не объявлены).

В любом случае, когда у вас есть RecordDecl, вы можете получить доступ к его членам через field_begin.

Очевидно, что когда вы сталкиваетесь с соседними классами, вам также необходимо перечислить их. Фактически, поскольку вы можете определять методы в классах в функциях, вам нужно проверять наличие вложенных объявлений почти везде.

1 голос
/ 07 июля 2011

Я согласен, что документация CLang может отсутствовать в некоторых областях.К сожалению, именно так работает Open Source: его будет не хватать до тех пор, пока он кому-то не понадобится, он не поймет, и решат внести свой вклад в его выводы.

Для вашей конкретной проблемы я предлагаю вам опубликоватьв списке рассылки Clang Dev (или начните с , просматривая архивы ).Вопросы об ASTConsumers или другом анализе преобразования довольно часто встречаются, и на них обычно быстро отвечают.

А потом, когда вы узнали, что искали, подумайте об обновлении документации;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...