如何通过LLVM中的成员函数获取C++类名及llvm::StructType*
LLVM 成员函数关联类信息的实现方法
一、通过成员函数获取C++类名
有两种可靠的实现方式:
方法1:从成员函数的this指针参数提取
非静态C++成员函数在LLVM IR中会被处理成带this指针作为第一个参数的普通函数。你可以解析这个参数的类型,拿到对应结构体类型后提取类名:
// 假设已获取目标成员函数的llvm::Function* Func if (!Func->isStaticMemberFunction()) { llvm::Argument* thisArg = &*Func->arg_begin(); if (auto thisPtrTy = llvm::dyn_cast<llvm::PointerType>(thisArg->getType())) { if (auto classStructTy = llvm::dyn_cast<llvm::StructType>(thisPtrTy->getElementType())) { llvm::StringRef fullName = classStructTy->getName(); // 从"class.Circle"中提取"Circle" llvm::StringRef className = fullName.split('.').second; // className即为目标C++类名 } } }
方法2:解析函数的mangled名称
Clang会给C++函数生成mangled名称,你可以用LLVM的demangle工具还原名称后提取类名:
llvm::StringRef mangledName = Func->getName(); std::string demangledName = llvm::demangle(mangledName.str()); // 从"Circle::getType()"中提取类名 size_t colonPos = demangledName.find("::"); if (colonPos != std::string::npos) { std::string className = demangledName.substr(0, colonPos); }
这种方法也适用于静态成员函数,但依赖mangling规则的兼容性,不如方法1直接可靠。
二、获取成员函数对应的llvm::StructType*
利用非静态成员函数的this指针参数特性,直接从参数类型解析即可,对应你示例中的%class.Circle:
// 假设已获取getType()对应的llvm::Function* func llvm::StructType* getClassStructType(llvm::Function* func) { if (func->isStaticMemberFunction()) { // 静态成员函数无this指针,需通过mangled名称等其他方式处理 return nullptr; } llvm::Argument* thisArg = &*func->arg_begin(); auto thisPtrTy = llvm::dyn_cast<llvm::PointerType>(thisArg->getType()); if (!thisPtrTy) return nullptr; return llvm::dyn_cast<llvm::StructType>(thisPtrTy->getElementType()); } // 调用后即可得到%class.Circle对应的StructType*指针 llvm::StructType* circleStructTy = getClassStructType(func);
针对你提供的Circle类示例,getType()函数在IR中的签名类似:
define i32 @_ZN6Circle7getTypeEv(%class.Circle* %this) #0 { ; ... 函数体 }
通过上述代码,就能从第一个参数%class.Circle* %this的类型中提取出对应的llvm::StructType*。
内容的提问来源于stack exchange,提问作者Crystal
相关产品推荐
相关产品推荐

