Получить Clang AST для одного файла - PullRequest
1 голос
/ 28 апреля 2019

Я использую Clang в расширении редактора кода для реализации свертывания / свертывания, и я столкнулся с проблемой.

Я анализирую только один файл за раз, а не весьпереводческий блок.Это отчасти для скорости и простоты, но также потому, что вы можете открыть файл заголовка самостоятельно и не знать, какой cpp все равно проанализировать.

Проблема в том, что как только clang встречает неизвестный символ, он просто отказываетсяи целые куски файла отсутствуют в AST.Рассмотрим следующий фрагмент

void Foo1()
{
    while (PeekMessageA())
    {
        switch (0)
        {
        }
    }
}

AST для этого просто

|-FunctionDecl 0x1fde8f67240 <Folding Test.cpp:1:1, line:9:1> line:1:6 Foo1 'void ()'
| `-CompoundStmt 0x1fde8f673f8 <line:2:1, line:9:1>

Нет информации для блока while или блока переключателей.Очевидно, что clang не может знать, является ли PeekMessageA вызовом функции или конструкцией объекта и т. Д., И я в порядке с этим.Мне не нужно, чтобы он был идеальным, но я хочу быть в состоянии добраться до времени и переключать блоки.

Есть ли способ получить Clang, чтобы предоставить больше информации в лицо в этом случае?В настоящее время я использую LibClang, но также могу использовать LibTooling.

1 Ответ

0 голосов
/ 21 мая 2019

Это не простая проблема, для которой нет идеального решения, но для ваших потребностей, которые кажутся ограниченными, вы можете найти решение.Проблема возникает из-за того, что C ++ имеет некоторые семантические неоднозначности, в отличие от других языков, которые имеют не более лексических неоднозначностей (например, C #), поэтому clang может не иметь возможности создать полный AST, когда файл не компилируется.

Это происходит по крайней мере из-за неоднозначности между выражениями и объявлениями.Синтаксическому анализатору C ++ может потребоваться разрешить некоторые символы, чтобы различать эти два синтаксиса.Когда это разрешение не удается, например, когда символ не может быть разрешен ни как тип, ни как переменная, clang выбрасывает целые части AST, потому что он просто не может его построить.

У меня былота же самая проблема много лет назад, и если я хорошо помню, когда в условии if произошла ошибка, то весь оператор if был отброшен.Следовательно, в этом случае, если вы хотите сохранить оператор if, вы должны взломать анализатор clang и создать узлы ошибок вместо выражения условия.Та же проблема возникает во всех других операторах, содержащих выражение или объявление.

Надеюсь, это поможет.

...