【问题标题】:libclang returns too much info about function declarationslibclang 返回太多关于函数声明的信息
【发布时间】:2013-12-15 08:30:02
【问题描述】:

我有以下使用 clang-c API 的代码。

#include <iostream>
#include <string>
#include <clang-c/Index.h>

CXChildVisitResult printVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) 
{       
    CXCursor cursor1 = clang_getCursorReferenced(cursor);

    CXType type = clang_getCursorType(cursor1);
    CXCursorKind kind = clang_getCursorKind(cursor1);
    CXString str = clang_getTypeSpelling(type);
    CXString str1 = clang_getCursorSpelling(cursor1);
    std::string cstr = clang_getCString(str);
    std::string cstr1 = clang_getCString(str1);

    if(type.kind != 0 && kind == CXCursorKind::CXCursor_FunctionDecl)
    {
        std::cout << "Declaration!\n" << "type is: " << cstr << std::endl;
        std::cout << "name is: " << cstr1 << std::endl;
    }

    return CXChildVisit_Recurse;
}

int main (int argc, char** argv)
{
 CXIndex index = clang_createIndex (
         false, // excludeDeclarationFromPCH
         true   // displayDiagnostics
 );
 CXTranslationUnit unit = clang_parseTranslationUnit (
         index,                           // CIdx
         "main1.cpp",                      // source_filename
         argv + 1 ,                        // command_line_args
         argc - 1 ,                        // num_command_line_args
         0,                                // unsave_files
         0,                                // num_unsaved_files
         CXTranslationUnit_None           // options
 );
 if (unit != 0 )
         std::cout << "Translation unit successfully created" << std::endl;
 else
         std::cout << "Translation unit was not created" << std::endl;

 CXCursor rootCursor = clang_getTranslationUnitCursor(unit);

    clang_visitChildren(rootCursor, printVisitor, NULL);


 clang_disposeTranslationUnit(unit);
 clang_disposeIndex(index);
}

此代码解析以下内容。

double getSum(double a, float b)
{
    return a + b;
}

int main(void)
{
    int a = 5;
    float b = 6;
    double c = a + b;
    return getSum(c, b);
}

程序运行时,我看到以下内容。

    Translation unit successfully created
    Declaration!
    type is: double (double, float)
    name is: getSum
    Declaration!
    type is: int ()
    name is: main
    Declaration!
    type is: double (double, float)
    name is: getSum
    Declaration!
    type is: double (double, float)
    name is: getSum
    Declaration!
    type is: double (double, float)
    name is: getSum
    Declaration!
    type is: double (double, float)
    name is: getSum

为什么我得到这么多getSum() 的声明,而在代码中我只有一个声明?

【问题讨论】:

    标签: c++ clang libclang


    【解决方案1】:

    当您使用clang_getCursorReferenced 时,您将获得在当前位置引用的CXCursor。例如,函数声明引用自身,并被相应的函数调用引用。因此,在您的示例中,您将获得对函数声明(函数声明本身或函数调用)的每个引用的正匹配。

    现在另一件事是每个CXCursor 代表 AST 的一部分,可以是叶子,也可以是带有子部分的更复杂的部分。例如,在遍历 AST 时,您会依次找到以下光标:

    • return getSum (c, b)
    • getSum (c, b)
    • getSum

    所有这些游标都引用了getSum函数声明,我猜这些游标会触发对getSum的多次引用。

    可以通过调用clang_getCursorExtent查看源码的哪一部分对应当前光标

    【讨论】:

      【解决方案2】:

      我从未使用过 clang,但基于 the documentation of CXCursor 似乎CXCursorKind 将永远是 Declaration 只要光标在函数中的某处main 可能会得到我想是特殊待遇)。这或许可以解释为什么您有多个关于 Sum 声明的报告。

      我的猜想基于CXCursorKind的定义,发现here

      enum CXCursorKind {
        /* Declarations */
        /**
         * \brief A declaration whose specific kind is not exposed via this
         * interface.
         *
         * Unexposed declarations have the same operations as any other kind
         * of declaration; one can extract their location information,
         * spelling, find their definitions, etc. However, the specific kind
         * of the declaration is not reported.
         */
      ...
      }
      

      【讨论】:

      • 你的回答让我明白了原因是使用 clang_getCursorReferenced;我不知道为什么,但是当使用简单的 CXCursor 时没关系:)谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 2015-01-23
      • 2014-09-05
      • 1970-01-01
      相关资源
      最近更新 更多