如何使用libclang获取C++类的完整数据布局?
问题:获取C++类的完整数据布局信息
我需要生成C++类的数据布局,具体需求如下:
- 获取类型
X对象的大小 - 获取类型
X对象的对齐方式 - 获取类型
X对象中每个数据组件(基类或成员)的偏移量
目前我能轻松获取前两项,也能拿到X的各成员偏移量,还能获取类的各基类游标并构建继承关系图,但无法获取X的每个基类的偏移量。
我的最终目标是拿到X的所有成员及其所有基类成员相对于X的偏移量,也就是Itanium C++ ABI第二章《数据布局》中描述的任意类X的相关信息。
我猜测这些信息可能不在AST中,仅针对Itanium的特定后端解析,但其他ABI特定信息(如类偏移量)是可以获取的。
编辑内容
在参考Scott McPeak的评论后,我查看了libclang内部实现,编写了一段看似可行但可能存在问题的hack代码,作为libclang API扩展测试。我明确这段代码存在问题,希望得到基于现有libclang API的正确方案。
这段代码基于clang_Type_getOffsetOf实现,返回比特单位的偏移量(与成员偏移量保持一致,尽管基类偏移量几乎不可能以比特为单位),其中CXTypeLayoutError_InvalidFieldName应替换为CXTypeLayoutError_InvalidBase或别名CXTypeLayoutError_InvalidFieldNameOrBase。
代码如下:
long long clang_Type_getOffsetOfBase(CXType PT, const CXIdxBaseClassInfo *BaseInfo) { // check that PT is not incomplete/dependent CXCursor PC = clang_getTypeDeclaration(PT); long long Error = validateFieldParentType(PC,PT); if (Error < 0) return Error; // get the record decl for PT ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext(); const CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(cxcursor::getCursorDecl(PC)); if (!RD) return CXTypeLayoutError_Invalid; // get the record decl for the base if (BaseInfo) { if (auto Spec = cxcursor::getCursorCXXBaseSpecifier(BaseInfo->cursor)) { if (auto BaseDecl = Spec->getType()->getAsCXXRecordDecl()) { return Ctx.toBits( Ctx.getASTRecordLayout(RD).getBaseClassOffset(BaseDecl)); } } } return CXTypeLayoutError_InvalidFieldName; }
内容的提问来源于stack exchange,提问作者Jody Hagins
相关产品推荐
相关产品推荐

