Я использую Clang для создания некоторых внутренних c анализаторов кода. Для одного из анализаторов нам нужно взять необработанную строку и проверить, нет ли в ней синтаксических ошибок. Мы не должны учитывать отсутствующие символы, заголовки, недопустимые вызовы функций и т. Д. c. как недопустимый синтаксис - поскольку единственное значение - проверить, является ли он действительным кодом C / C ++ или нет.
Сначала я думал, что могу сделать это с помощью ASTUnit
:
auto AST = tooling::buildASTFromCodeWithArgs(MyCode,
Args,
"input.cc",
"clang-tool",
std::make_shared<PCHContainerOperations>(),
tooling::getClangStripDependencyFileAdjuster(),
tooling::FileContentMappings(),
&DiagConsumer);
llvm::outs() << "hasUncompilableErrorOccurred " << AST->getDiagnostics().hasUncompilableErrorOccurred() << "\n";
llvm::outs() << "hasUnrecoverableErrorOccurred " << AST->getDiagnostics().hasUnrecoverableErrorOccurred() << "\n";
llvm::outs() << "hasErrorOccurred " << AST->getDiagnostics().hasErrorOccurred() << "\n";
Принимая два входа: Hello world
и #include <undefined.h>
- оба дают 1 в выходных данных выше - даже если #include <undefined.h>
является правильным выражением C, но проблема с ним (в отличие от hello world
, который не является допустимым C код) - это то, что undefined.h
отсутствует. Точно так же использование: int* p = malloc(sizeof(int));
в качестве кода приведет к ошибке во всех этих вызовах, если stdlib.h
не было включено.
Я стараюсь избегать таких ошибок, поэтому во всех случаях, кроме hello world
, будет считаться действительным кодом.
Я пытался перебрать его, создав Raw Lexer, но он не дал мне достаточной информации.
Lexer Lex(CharRange.getBegin(), PP->getLangOpts(), Text.data(),
Text.data(), Text.data() + Text.size());
Token RawTok;
do {
Lex.LexFromRawLexer(RawTok);
llvm::outs() << "\t- " << RawTok.getKind() << "\n";
} while (RawTok.isNot(tok::eof));
Я бы хотел получить любые предложения!