Начал изучения библиотеки clang для парсинга кода. Мне необходимо найти все комментарии. Если использовать clang-c, то для этого у меня есть код:
...
unsigned numTokens = 0;
CXToken *tokens = NULL;
clang_tokenize(_tu, range, &tokens, &numTokens);
size_t resLine = 0;
for(unsigned i = 0 ; i < numTokens; i++)
{
enum CXTokenKind kind = clang_getTokenKind(tokens[i]);
if(kind == CXToken_Comment)
{
const std::string commentText = clang_getCString(clang_getTokenSpelling(_tu, tokens[i]));
...
}
}
...
По некоторым причинам я сейчас использую c++ интерфейс библиотеки clang и я не могу разобраться как мне сделать тоже самое с++ кодом. Подскажите в какое направление копать, какие классы использовать.
UPD1: clang предоставляет 2 интерфейса для работы с кодом, Си интерфейс и C++ интерфейс. Вышеприведенный код использует Си интерфейс, мне нужен тот же функциона но с использование с++ интерфейса. В данном контексте clang не используется для компиляции программы, как gcc или msvc,а для анализа кода, подобно тому как это делает clang-format или clang-check.
Поковырял реализацию метода clang_tokenize
и в итоге написал код сам, может кому то пригодится.
struct CommentInfo
{
std::string content;
SourceLocation loc;
};
class CommentParser
{
public:
CommentParser(ASTContext& _ctx, SourceManager& _sm):
ctx(_ctx),
sm(_sm)
{
}
std::vector<CommentInfo> getAllComments()
{
std::vector<CommentInfo> out;
SourceLocation locStart = sm.getLocForStartOfFile(sm.getMainFileID());
SourceLocation locEnd = sm.getLocForEndOfFile(sm.getMainFileID());
SourceRange Range(locStart, locEnd);
std::pair<FileID, unsigned> BeginLocInfo =
sm.getDecomposedSpellingLoc(Range.getBegin());
std::pair<FileID, unsigned> EndLocInfo =
sm.getDecomposedSpellingLoc(Range.getEnd());
ms_assert(BeginLocInfo.first == EndLocInfo.first, "Cannot tokenize across files.");
// Create a lexer
bool Invalid = false;
StringRef Buffer = sm.getBufferData(BeginLocInfo.first, &Invalid);
ms_assert(!Invalid, "Error while create lexer");
Lexer Lex(sm.getLocForStartOfFile(BeginLocInfo.first),
ctx.getLangOpts(), Buffer.begin(),
Buffer.data() + BeginLocInfo.second, Buffer.end());
Lex.SetCommentRetentionState(true);
// Lex tokens until we hit the end of the range.
const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Token Tok;
bool previousWasAt = false;
do {
// Lex the next token
Lex.LexFromRawLexer(Tok);
if (Tok.is(tok::eof))
{
break;
}
if(Tok.is(tok::comment))
{
std::pair<FileID, unsigned> LocInfo =
sm.getDecomposedSpellingLoc(Tok.getLocation());
CommentInfo cInfo;
cInfo.content = Buffer.substr(LocInfo.second, Tok.getLength());
cInfo.loc = Tok.getLocation();
out.push_back(cInfo);
}
previousWasAt = Tok.is(tok::at);
} while (Lex.getBufferLocation() < EffectiveBufferEnd);
return out;
}
private:
ASTContext& ctx;
SourceManager& sm;
};
Использовать так:
ASTContext& ctx = d->getASTContext();
SourceManager& sm = ctx.getSourceManager();
CommentParser cParser(ctx, sm);
for(auto &it : cParser.getAllComments())
{
std::cout << it.loc.printToString(sm) << "\n" << it.content << "\n\n";
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Каким образом в QT можно получить превью картинки с яндекскартинок
Всем добрый вечер! Столкнулся с потребностью сверхскростного обращения матриц без использования nplinalg