相关的API https://clang.llvm.org/doxygen/group__CINDEX__TYPES.html
ref:
- https://stackoverflow.com/questions/25231080/what-are-canonical-types-in-clang
- usage: https://clang.llvm.org/docs/LibClang.html
- https://clang.llvm.net.cn/docs/LibClang.html
- example: https://blog.csdn.net/qq_45335399/article/details/113727548
// libclang_parser.cpp
// 定义递归访问函数
std::function<void(CXCursor)> visitNode = [&](CXCursor cursor) {
// 添加调试信息
CXCursorKind kind = clang_getCursorKind(cursor);
CXString cursor_kind_spelling = clang_getCursorKindSpelling(kind);
std::cout << "Cursor kind: " << clang_getCString(cursor_kind_spelling) << "\n";
clang_disposeString(cursor_kind_spelling);
// 处理所有声明和类型引用
if (clang_isDeclaration(kind) || clang_isReference(kind) || clang_isExpression(kind)) {
// 获取类型的完整字符串表示
CXType type = clang_getCursorType(cursor);
// 使用 CanonicalType 生成 key,和 cppast::to_string() 生成的格式一致
CXType canonical_type = clang_getCanonicalType(type);
CXString canonical_spelling = clang_getTypeSpelling(canonical_type);
std::string cppast_key = clang_getCString(canonical_spelling);
clang_disposeString(canonical_spelling);
// 同时获取 libclang 原始的类型字符串
CXString type_spelling = clang_getTypeSpelling(type);
std::string libclang_type = clang_getCString(type_spelling);
clang_disposeString(type_spelling);
// 获取 cursor 的“书写”,即它在源代码中的标识
CXString cursorSpelling = clang_getCursorSpelling(cursor);
std::cout <<"Cursor Spelling: " << clang_getCString(cursor_kind_spelling) << ": " << clang_getCString(cursorSpelling) << "\n";
CXCursor declCursor = clang_getTypeDeclaration(type);
if (!clang_Cursor_isNull(declCursor)) {
CXString typedefName = clang_getCursorSpelling(declCursor);
std::string source_typedef_name = clang_getCString(typedefName);
clang_disposeString(typedefName);
std::cout << "Typedef spelling as in source: " << source_typedef_name << std::endl;
}
std::cout << "Generated key: " << cppast_key << "\n";
std::cout << "Original libclang type: " << libclang_type << "\n" << std::endl;
if (!libclang_type.empty() && !cppast_key.empty()) {
pimpl_->type_spelling_map[cppast_key] = libclang_type;
}
}
// 递归访问子节点
clang_visitChildren(cursor,
[](CXCursor child, CXCursor parent, CXClientData client_data) {
auto& visit = *reinterpret_cast<std::function<void(CXCursor)>*>(client_data);
visit(child);
return CXChildVisit_Continue;
},
&visitNode);
};
// 从根节点开始访问
CXCursor root = clang_getTranslationUnitCursor(tu.get());
visitNode(root);
// output result
Cursor kind: CXXMethod
Cursor Spelling: CXXMethod: preloadChannel
Typedef spelling as in source:
Generated key: int (const char *, const char *, unsigned int)
Original libclang type: int (const char *, const char *, agora::rtc::uid_t)
Cursor kind: ParmDecl
Cursor Spelling: ParmDecl: token
Typedef spelling as in source:
Generated key: const char *
Original libclang type: const char *
Cursor kind: ParmDecl
Cursor Spelling: ParmDecl: channelId
Typedef spelling as in source:
Generated key: const char *
Original libclang type: const char *
Cursor kind: ParmDecl
Cursor Spelling: ParmDecl: uid
Typedef spelling as in source: uid_t
Generated key: unsigned int
Original libclang type: agora::rtc::uid_t
Cursor kind: TypeRef
Cursor Spelling: TypeRef: agora::rtc::uid_t
Typedef spelling as in source: uid_t
Generated key: unsigned int
Original libclang type: agora::rtc::uid_t