我有以下使用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
为什么我在{1}}中获得了如此多的声明,在代码中我有一个声明?
答案 0 :(得分:5)
使用clang_getCursorReferenced
时,您会获得当前位置引用的CXCursor
。例如,函数声明引用自身,并由相应的函数调用引用。在您的示例中,您将因此获得对函数声明(函数声明本身或函数调用)的每个引用的正匹配。
现在另一件事是每个CXCursor
代表AST的一部分,无论是叶子还是带有子部分的更复杂的部分。例如,在遍历AST时,您将依次找到以下游标:
return getSum (c, b)
getSum (c, b)
getSum
所有这些游标都引用了getSum
函数声明,我的猜测是这些游标会触发对getSum
的多次引用。
您可以通过调用clang_getCursorExtent
答案 1 :(得分: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.
*/
...
}