如何从LLVM 7.0的TBAA元数据节点(MDNode)中获取类型?
解决LLVM 7.0下从TBAA元数据节点获取类型的问题
这个问题的核心是LLVM版本迭代中元数据系统的API变更:在LLVM 3.3中,MDNode::getOperand()直接返回Value*,所以你可以直接调用getType();但到了LLVM 7.0,元数据系统做了重构,getOperand()返回的是MDOperand类型——这是一个轻量级的包装器,内部持有Metadata*,而Metadata基类并没有getType()方法,因此会触发编译错误。
针对TBAA元数据节点的类型获取,你需要根据元数据的实际类型,将MDOperand转换为对应的Metadata子类,再提取出对应的Value和类型:
具体修复代码示例
// 先从MDOperand中提取Metadata指针 Metadata *MD = UTBAATag->getOperand(i).get(); // 判断是否是包裹了Value的ValueAsMetadata if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) { Value *Val = VAM->getValue(); Type *ElTy = Val->getType(); // 这里可以继续你的后续逻辑 } // 如果你的TBAA标签操作数是MDString(比如类型名称),可以这样处理 else if (auto *MDS = dyn_cast<MDString>(MD)) { StringRef TypeName = MDS->getString(); // 如果你需要从类型名称映射到Type*,可以通过LLVM上下文查找 // 比如:Type *ElTy = Type::getTypeByName(UTBAATag->getContext(), TypeName); }
关键说明
MDOperand::get()方法用于获取内部的Metadata*实例,这是访问元数据内容的第一步。ValueAsMetadata是LLVM用于将Value*嵌入元数据的包装类,通过getValue()可以还原出原始的Value对象,进而调用getType()。- 如果你的TBAA元数据中存储的是类型名称字符串(以
MDString形式存在),则需要通过LLVM上下文的getTypeByName()方法将字符串转换为Type*。
这个适配方案既兼容了LLVM 7.0的元数据API,也能准确还原你在LLVM 3.3中获取类型的逻辑。
内容的提问来源于stack exchange,提问作者Rambo
相关产品推荐
相关产品推荐

