我正在使用 Libtooling 来解析 Windows SDK 标头,但是在获取函数调用约定时存在问题,libtooling 总是返回__cdell
或WINAPI
调用__stdcall
约定,这是 Win32 API 的默认调用约定。
这是一个输入示例
VOID
__stdcall
TestFunction (_In_ BOOLEAN is_valid);
这是我的函数访问者函数RecursiveASTVisitor
virtual bool VisitFunctionDecl(clang::FunctionDecl *func)
{
// ...
if (m_AstContext->getSourceManager().isInMainFile(func->getLocation()))
{
if (func->hasAttrs())
{
auto stdcall = func->hasAttr<StdCallAttr>(); // always return False
}
const clang::FunctionProtoType * prototype = func->getType()->getAs<FunctionProtoType>();
if (prototype)
{
auto stdcall = prototype->hasAttr(attr::Kind::StdCall); // always return False
errs() << clang::FunctionType::getNameForCallConv(prototype->getCallConv()).str() << " "; // always return cdecl
}
func->dumpColor(); // But there is __attribute__((stdcall)) in dumped output!
}
// ...
}
最后输出func->dumpColor();
输入示例!
^
FunctionDecl 0x218c95bb6f0 <C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\winnt.h:430:14, C:\ExampleInput.h:18:36> col:1 TestFunction 'void (BOOLEAN) __attribute__((stdcall))':'void (BOOLEAN)'
`-ParmVarDecl 0x218c95bb5c0 <col:20, col:28> col:28 is_valid 'BOOLEAN':'unsigned char'
出于兼容性原因,我也使用/不使用此选项运行它,但根本没有区别:-(
-fms-compatibility
-fms-extensions
-fms-compatibility-version=19
任何想法?
更新
我发现了问题,这是因为#Clang 的默认编译配置。它是 64 位(在 64 位工具链中),并且在 64 位模式下无法__stdcall
使用如果我使用 32 位版本(或 -m32 选项),那么它将正常工作
知道为什么它会在 64 位模式下发生吗?