如何使用 C API 而不是实际使用 Clang 了解编写的 var 类型
How to know written var type with Clang using C API instead of actual?
我正在尝试通过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 %sn", clang_getCString(returnTypeSpelling));
clang_disposeString(returnTypeSpelling);
}
输出:
[105:10 4689] 访问=[CX_CXXPublic] 种类=[CXIdxEntity_CXXInstanceMethod] (21) name=[setFirmwareNameAndVersion] is_container=[0] 3 参数:
种类=[CXCursor_ParmDecl (10)], 类型=[常量字符 *], 拼写=[名称]
种类=[CXCursor_ParmDecl (10)], 类型=[int], 拼写=[主要]
种类=[CXCursor_ParmDecl (10)], 类型=[整数], 拼写=[次要] 返回无效
所以你可以看到byte
函数参数被描述为 int
.如何获得实际拼写?
byte
是通过 typedef 还是 #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 )
Libclang 大概无法打印 #defined 名称,因为在构建解析树时,预处理器已经将其替换为int
。
几天前我已经解决了这个问题。
"Stream &" becomes "int &" and "byte" becomes "int.
libclang 不知道Stream
或byte
是什么,直到您使用标志手动插入标准标头-isystem <pathToStdHeaderDirectory>
我编写了一个 C# 函数,用于检索所有 Visual Studio VC 标头包含目录:
private static string[] GetStdIncludes()
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWAREWow6432NodeMicrosoftVisualStudio"))
{
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");
}
希望有帮助
我在自己的课程中遇到了同样的问题。
您需要将用于编译 clang 的相同标志传递给 clang_parseTranslationUnit 或 clang_createTranslationUnit,特别是用于查找类或类型定义所在的头文件的 -I 标志。似乎如果 libclang 找不到类型声明,它只是默认为 all 然后为 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 参数。
- 正在尝试了解输入验证循环
- 了解 GLM- openGL 中的相机转换
- 奇怪的结构&GCC&clang(void*返回类型)
- C++我需要了解在哪里使用指针和双指针
- 如何深入了解明显的腐败
- 数据成员SFINAE的C++17测试:gcc vs clang
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- Clang bug?使用指针作为模板参数
- clang整洁10忽略了我的NOLINT命令
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在clang++预处理器中确定gcc工具链版本
- 为什么 Clang 不允许"and"作为函数名称?
- 带有 -stdlib=libc++ 的 clang++ 9.0.1 找不到<optional>
- clang格式:宏的缩进
- CLANG 编译器 说:变量"PTR"可能未初始化
- clang格式:禁用排序包含
- 在继承多个空类时,了解GCC/Clang vs MSVC2015之间的不同填充规则
- 如何使用 C API 而不是实际使用 Clang 了解编写的 var 类型