我有一个Function
传递,称为firstPass
,它进行一些分析并填充:
A a;
哪里
typedef std::map< std::string, B* > A;
class firstPass : public FunctionPass {
A a;
}
typedef std::vector< C* > D;
class B {
D d;
}
class C {
// some class packing information about basic blocks;
}
因此,我有一张std::string
遍历的向量图。 我为这些类编写了关联的析构函数。此通行证可自行成功运行。
我还有另一个Function
传递,称为secondPass
,需要这种类型A
的结构来进行一些转换。我用了
bool secondPass::doInitialization(Module &M) {
errs() << "now running secondPassn";
a = getAnalysis<firstPass>().getA();
return false;
}
void secondPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<firstPass>();
AU.setPreservesAll();
}
整个代码编译良好,但是只有当我调用第二次传递时,我在第一次传递结束时打印此结构时才会出现分段错误(因为B*
为 null(。
需要明确的是:
opt -load ./libCustomLLVMPasses.so -passA < someCode.bc
在doFinalization()
中打印并成功退出
opt -load ./libCustomLLVMPasses.so -passA -passB < someCode.bc
给出分段错误。
我应该如何包装此数据结构并将其毫无问题地传递给第二次传递?我尝试了std::unique_ptr
而不是原始的,但我无法让它工作。无论如何,我不确定这是否是正确的方法,因此任何帮助将不胜感激。
编辑:我解决了赛格的问题。故障。基本上是我在doInitialization((中调用getAnalysis。我写了一个 ModulePass 来组合我的 firstPass 和 secondPass,其 runOnModule 如下所示。
bool MPass::runOnModule(Module &M) {
for(Function& F : M) {
errs() << "F: " << F.getName() << "n";
if(!F.getName().equals("main") && !F.isDeclaration())
getAnalysis<firstPass>(F);
}
StringRef main = StringRef("main");
A& a = getAnalysis<firstPass>(*(M.getFunction(main))).getA();
return false;
}
这也使我能够控制所处理函数的顺序。 现在我可以获取一个传递的输出,但不能将其用作另一个传递的输入。我认为这表明 llvm 中的传递是自包含的。
我不打算根据数据结构C++优点来评论数据结构的质量(仅通过这个最小的例子很难对此进行评论(。
此外,如果实际初始化如此简单,我不会使用doInitialization
方法,但这也是一个附带评论。(该文档没有明确提及任何有关它的内容,但如果它每Module
运行一次,而runOn
方法在该模块的每个Function
上运行,则可能是个问题(。
我怀疑主要问题似乎源于firstPass
中的A a
绑定到传递对象的生存期,一旦传递完成,该生存期就结束了。最简单的更改是在堆上分配该对象(例如new
(,并在调用getAnalysis<firstPass>().getA();
时返回指向它的指针。
请注意,如果您决定使用原始指针,则使用此方法可能需要手动清理。