Я знаю, что это никогда не будет полностью точным без заголовков, потому что C ++ не является контекстно-свободным.
Использование классического примера «A B (C);» означает, что его можно распознать как объявление функции или определение объекта. Либо хорошо для меня. Мне просто нужно полностью разобрать файл.
Меня не интересует семантический анализ кода, только синтаксический, и AFAIK грамматика clang — одна из лучших.
Проблема в том, что в некоторых сценариях Clang избегает некоторых объявлений, когда он не знает типов, хотя я думаю, что он может правильно его проанализировать.
Смотрите следующий случай. Содержание class.cpp:
A::A() { }
A::~A() { }
void A::B() { }
A::C() { }
Выполнение приложения командной строки clang:
$ clang -Xclang -ast-dump -fsyntax-only class.cpp
он просто распознает в качестве узлов AST конструктор и последний метод.
typedef char *__builtin_va_list;
int A() (CompoundStmt 0x9a6a570 <class.cpp:3:8, col:10>)
int C() (CompoundStmt 0x9a6a600 <class.cpp:9:8, col:10>)
Есть ли способ получить полное дерево AST?
Спасибо!
Я не уверен, что это то, что вам нужно:
test.cpp:
class A {
A();
~A();
void B();
void C();
};
A::A() {}
A::~A() {}
void A::B() {}
void A::C() {}
Для сброса AST используйте: clang -Xclang -ast-dump -fsyntax-only test.cpp
TranslationUnitDecl 0x204f150 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x204f690 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
|-TypedefDecl 0x204f6f0 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
|-TypedefDecl 0x204fab0 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
|-CXXRecordDecl 0x204fb00 <test.cpp:1:1, line:6:1> line:1:7 class A definition
| |-CXXRecordDecl 0x204fc10 <col:1, col:7> col:7 implicit class A
| |-CXXConstructorDecl 0x204fd10 <line:2:5, col:7> col:5 A 'void (void)'
| |-CXXDestructorDecl 0x2088cc0 <line:3:5, col:8> col:5 ~A 'void (void)'
| |-CXXMethodDecl 0x2088d90 <line:4:5, col:12> col:10 B 'void (void)'
| |-CXXMethodDecl 0x2088e50 <line:5:5, col:12> col:10 C 'void (void)'
| `-CXXConstructorDecl 0x2088f80 <line:1:7> col:7 implicit A 'void (const class A &)' inline noexcept-unevaluated 0x2088f80
| `-ParmVarDecl 0x20890c0 <col:7> col:7 'const class A &'
|-CXXConstructorDecl 0x2089120 parent 0x204fb00 prev 0x204fd10 <line:8:1, col:9> col:4 A 'void (void)'
| `-CompoundStmt 0x2089218 <col:8, col:9>
|-CXXDestructorDecl 0x2089280 parent 0x204fb00 prev 0x2088cc0 <line:9:1, col:10> col:4 ~A 'void (void)'
| `-CompoundStmt 0x2089368 <col:9, col:10>
|-CXXMethodDecl 0x20893c0 parent 0x204fb00 prev 0x2088d90 <line:10:1, col:14> col:9 B 'void (void)'
| `-CompoundStmt 0x2089498 <col:13, col:14>
`-CXXMethodDecl 0x20894f0 parent 0x204fb00 prev 0x2088e50 <line:11:1, col:14> col:9 C 'void (void)'
`-CompoundStmt 0x20895c8 <col:13, col:14>
Других решений пока нет …