8

libclangを使用してプリミティブリテラルの値を取得するにはどうすればよいですか?

たとえば、カーソルの種類がCXCursor_IntegerLiteralのCXCursorがある場合、リテラル値を抽出するにはどうすればよいですか。


アップデート:

libclangを使用すると非常に多くの問題が発生しました。私はそれを完全に避け、代わりにclangが提供するC++インターフェースを使用することを強くお勧めします。C ++インターフェースは非常に使いやすく、十分に文書化されています:http: //clang.llvm.org/doxygen/annotated.html

libclangの唯一の目的は、次のコードのようにASTUnitオブジェクトを生成することです(それ以外の場合は簡単ではありません)。

ASTUnit * astUnit;
{
    index = clang_createIndex(0, 0);
    tu = clang_parseTranslationUnit(
        index, 0,
        clangArgs, nClangArgs,
        0, 0, CXTranslationUnit_None
        );
    astUnit = static_cast<ASTUnit *>(tu->TUData);
}

ここで、libclangは安定しているが、C++インターフェースは安定していないと言うかもしれません。libclangを使用してASTを理解し、それを使用してクラッジを作成するために費やす時間は、とにかく多くの時間を浪費するため、これはほとんど問題になりません。バージョンのアップグレード後にコンパイルされないコードを修正するのに数時間を費やしたいと思います(必要な場合でも)。

4

4 に答える 4

9

オリジナルを再解析する代わりに、翻訳単位内に必要なすべての情報をすでに持っています。

if (kind == CXCursor_IntegerLiteral)
{
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXToken *tokens = 0;
    unsigned int nTokens = 0;
    clang_tokenize(tu, range, &tokens, &nTokens);
    for (unsigned int i = 0; i < nTokens; i++)
    {
        CXString spelling = clang_getTokenSpelling(tu, tokens[i]);
        printf("token = %s\n", clang_getCString(spelling));
        clang_disposeString(spelling);
    }
    clang_disposeTokens(tu, tokens, nTokens);
}

最初のトークンは整数自体であり、次のトークンは関係ありません (たとえば;int i = 42;.

于 2012-06-19T19:58:06.363 に答える
1

元のファイルを参照して、これを行う方法を見つけました。

std::string getCursorText (CXCursor cur) {
    CXSourceRange range = clang_getCursorExtent(cur);
    CXSourceLocation begin = clang_getRangeStart(range);
    CXSourceLocation end = clang_getRangeEnd(range);
    CXFile cxFile;
    unsigned int beginOff;
    unsigned int endOff;
    clang_getExpansionLocation(begin, &cxFile, 0, 0, &beginOff);
    clang_getExpansionLocation(end, 0, 0, 0, &endOff);
    ClangString filename = clang_getFileName(cxFile);
    unsigned int textSize = endOff - beginOff;

    FILE * file = fopen(filename.c_str(), "r");
    if (file == 0) {
        exit(ExitCode::CANT_OPEN_FILE);
    }
    fseek(file, beginOff, SEEK_SET);
    char buff[4096];
    char * pBuff = buff;
    if (textSize + 1 > sizeof(buff)) {
        pBuff = new char[textSize + 1];
    }
    pBuff[textSize] = '\0';
    fread(pBuff, 1, textSize, file);
    std::string res(pBuff);
    if (pBuff != buff) {
        delete [] pBuff;
    }
    fclose(file);
    return res;
}
于 2012-05-21T21:09:30.203 に答える