6

私は C API 経由で Clang を使用しようとしています。問題は、一部の型が記述どおりではなく、コンパイラ用として返されることです。たとえば、"Stream &" は "int &" になり、"byte" は "int.

いくつかのテスト ライブラリ:

// TODO make it a subclass of a generic Serial/Stream base class
class FirmataClass
{
public:
    FirmataClass(Stream &s);

    void setFirmwareNameAndVersion(const char *name, byte major, byte minor);

コードを使用してメソッド情報を取得しています。

void showMethodInfo(const CXIdxDeclInfo *info) {
    int numArgs = clang_Cursor_getNumArguments(info->cursor);
    fprintf(stderr, "  %i args:\n", numArgs);

    for (int i=0; i<numArgs; i++) {
        CXCursor argCursor = clang_Cursor_getArgument(info->cursor, i);
        CXString name = clang_getCursorDisplayName(argCursor);
        CXString spelling = clang_getCursorSpelling(argCursor);

        CXType type = clang_getCursorType(argCursor);
        CXString typeSpelling = clang_getTypeSpelling(type);

        CXCursorKind kind = clang_getCursorKind(argCursor);

        fprintf(stderr, "  kind=[%s (%i)], type=[%s], spelling=[%s]\n",
            cursor_kinds[kind], kind, clang_getCString(typeSpelling),
            clang_getCString(spelling));

        clang_disposeString(name);
        clang_disposeString(spelling);
        clang_disposeString(typeSpelling);
    }

    // return type
    CXType returnType = clang_getCursorResultType(info->cursor);
    CXString returnTypeSpelling = clang_getTypeSpelling(returnType);

    fprintf(stderr, " returns %s\n", clang_getCString(returnTypeSpelling));
    clang_disposeString(returnTypeSpelling);
}

出力:

[105:10 4689] access=[CX_CXXPublic] kind=[CXIdxEntity_CXXInstanceMethod] (21) name=[setFirmwareNameAndVersion] is_container=[0] 3 つの引数:
kind=[CXCursor_ParmDecl (10)]、type=[const char *]、スペル=[name]
kind=[CXCursor_ParmDecl (10)]、type=[int]、spelling=[major]
kind=[CXCursor_ParmDecl (10)]、type=[int]、spelling=[minor] void を返す

byteしたがって、関数の引数は のように記述されていることがわかりますint。どうすれば実際のスペルを取得できますか?

4

3 に答える 3

2

bytetypedef または #define で宣言されていますか?

これらの型を宣言すると:

typedef int MyType_t;
#define MyType2_t int

class Foo
{
public:
    bool bar( MyType_t a, MyType2_t b );
};

そして、これから得た型名を出力しclang_GetTypeSpellingます。

bool Foo_bar(  MyType_t a, int b )

int解析ツリーが構築されるまでにプリプロセッサがすでに #defined 名を置き換えているため、Libclang はおそらく #defined 名を出力できません。

于 2014-02-24T04:46:46.773 に答える
2

私は数日前にこれを解決しました。

"Stream &" becomes "int &" and "byte" becomes "int.

フラグを使用して手動で標準ヘッダーを挿入するまで、 libclang は何がStreamまたは何であるかを認識しません。byte-isystem <pathToStdHeaderDirectory>

すべてのビジュアル スタジオ VC ヘッダー インクルード ディレクトリを取得する C# 関数を作成しました。

    private static string[] GetStdIncludes()
    {

        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\VisualStudio"))
        {
            if (key != null)
            {
                var lastVcVersions = key.GetSubKeyNames()
                    .Select(s =>
                    {
                        float result = 0;
                        if (float.TryParse(s, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out result))
                            return result;
                        else return 0F;

                    }).Where(w => w > 0F)
                    .OrderByDescending(or => or)
                    .Select(s => s.ToString("n1", System.Globalization.CultureInfo.InvariantCulture))
                    .ToArray();

                foreach (var v in lastVcVersions)
                {
                    using (var vk = key.OpenSubKey(v))
                    {
                        var val = (string)vk.GetValue("Source Directories");

                        if (!string.IsNullOrEmpty(val))
                            return val.Split(";");
                    }
                }


            }
        }
        throw new Exception("Couldn't find VC runtime include directories");
    }

それが役立つことを願っています

于 2018-09-19T05:11:44.067 に答える
1

私は自分のクラスで同じ問題を抱えていました。

clang でコンパイルするために使用するのと同じフラグを、clang_parseTranslationUnit または clang_createTranslationUnit のいずれかに渡す必要があります。特に、クラスまたは型の定義があるヘッダー ファイルを検索するために使用される -I フラグです。libclang が型宣言を見つけられない場合、デフォルトですべてが int になるようです。

clang_createIndex ( 1, 1 ) を呼び出すと、stderr を介して何が欠けているかについてのヒントが得られるはずです。

これが今私のために働くいくつかのサンプルコードです:

int main ( int argc, char* argv[] )
{
    char *clang_args[] =
    {
        "-I.",
        "-I./include",
        "-I../include",
        "-x",
        "c++",
        "-Xclang",
        "-ast-dump",
        "-fsyntax-only",
        "-std=c++1y"
    };
    CXIndex Idx = clang_createIndex ( 1, 1 );
    CXTranslationUnit TU = clang_parseTranslationUnit ( Idx, argv[1], clang_args, 9, NULL, 0, CXTranslationUnit_Incomplete | CXTranslationUnit_SkipFunctionBodies );
    clang_visitChildren ( clang_getTranslationUnitCursor ( TU ),
                          TranslationUnitVisitor, NULL );
    clang_disposeTranslationUnit ( TU );
    return 0;
}

ヘッダー ファイルの AST を取得しようとしているため、CXTranslationUnit_Incomplete | CXTranslationUnit_SkipFunctionBodies フラグと -ast-dump -fsyntax-only コマンド ライン オプションを使用する必要がない場合は省略できます。もちろん、必要に応じて -I パラメータを追加および変更します。

于 2015-01-05T07:00:08.543 に答える