首先,我是LLVM通行证的新手.
我试图在转换过程之后(使用C++ API)向LLVM中的指令添加元数据.我打算存储此信息以供工具链中的其他工具使用.我有两个问题.
我希望我存储的信息作为元数据提供给另一个工作在LLVM IR上的工具.元数据是个好主意吗?我打算将字符串存储为带有一些指令的元数据.
如果元数据是正确的方式,我需要一些帮助来创建元数据节点.我打算使用setMedata()函数将它附加到指令.setMetadata()的哪个变体是正确使用的变体.我不确定我的数据应该是哪个MDKind.我想创建一个MDString,将它附加到我的MDNode,然后用一条指令调用setMetadata().如果我想将元数据附加到函数内的指令,我应该在setMedata()中使用什么上下文.上下文与元数据的相关性是什么?
我尝试在论坛和llvm doxygen文档中阅读了很多讨论,但我没有得到一个清晰而完整的答案来回答我的所有问题.我感谢您的帮助或一些可以帮助我理解这一点的材料.
我想重写我的代码中的所有消息,我只需要替换选择器,但我需要能够替换嵌套的表达式fe:
[super foo:[someInstance someMessage:@""] foo2:[someInstance someMessage2]];
Run Code Online (Sandbox Code Playgroud)
我尝试使用clang::Rewriter replaceText并生成新的字符串,但是有一个问题:如果我更改选择器长度,它将无法工作,因为我用那些旧位置替换嵌套消息.
所以,我认为我需要使用 clang::Rewriter ReplaceStmt(originalStatement, newStatement);
我RecursiveASTVisitor用来访问所有消息,我想复制这些消息对象,并替换选择器:
我怎样才能做到这一点?
我试过使用ObjCMessageExpr::Create但是有如此经典的args,我不知道如何从原始消息中获取ASTContext &Context and ArrayRef<SourceLocation> SeLocs和Expr *Receiver参数.
使用clang工具(clang工具界面)替换嵌套消息中选择器的正确方法是什么?
更新:
我应该使用ReplaceStmtWithStmt回调ASTMatchFinder吗?
更新:
我正在使用以下函数来重写文件中的文本:
void ReplaceText(SourceLocation start, unsigned originalLength, StringRef string) {
m_rewriter.ReplaceText(start, originalLength, string);
m_rewriter.overwriteChangedFiles();
}
Run Code Online (Sandbox Code Playgroud)
我想用新的选择器替换代码中的所有messageExpr:它是怎么回事:
[object someMessage:[object2 someMessage:obj3 calculate:obj4]];
Run Code Online (Sandbox Code Playgroud)
怎么样:
[object newSelector:[object2 newSelector:obj3 newSelector:obj4]];
Run Code Online (Sandbox Code Playgroud)
我正在使用ReqoursiveASTVisitor:
bool VisitStmt(Stmt *statement) {
if (ObjCMessageExpr *messageExpr = dyn_cast<ObjCMessageExpr>(statement)) {
ReplaceMessage(*messageExpr)
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
我创建了生成新消息expr字符串的方法:
string …Run Code Online (Sandbox Code Playgroud) 现在我们按照本教程实现llvm的分析传递.并需要将一个额外的参数传递给插件,如下所示:
opt -load /path/to/myplugin.so -mypass -mypass_option input.bc
Run Code Online (Sandbox Code Playgroud)
但是我没有找到任何手册告诉我该怎么做.所以我想知道它是否有可能在实践中.
提前致谢.
我正在研究用C++编写的高性能系统.该过程需要能够在运行时理解一些使用为此应用程序开发的简单语言编写的复杂逻辑(规则).我们有两种选择:
解释逻辑 - 运行嵌入式解释器并生成动态函数调用,当接收数据时,基于解释逻辑处理数据
将逻辑编译成plugin.so动态共享文件,使用dlopen,dlsym加载插件并在运行时调用逻辑函数
选项2看起来非常有吸引力,因为它将是优化的机器代码,在运行过程中运行速度比嵌入式解释器快得多.
我正在探索的选项是:
如果我是正确的,LLVM IR将转换为LLVM字节代码或汇编代码.然后使用LLVM JIT在JIT模式下运行或使用GNU Assembler用于生成本机代码.
是否有可能在LLVM中找到这样做的功能?如果它是从代码中完成的,而不是使用来自C++的系统命令来调用"as"来生成我的需求的plugin.so文件,那将会更好.
如果您知道我可以在运行时从我的进程生成共享库本机二进制代码的任何方法,请通知我.
我目前正在使用LLVM's ObjectFile(此处记录)来表示可执行文件.我已成功读取可执行文件,ObjectFile并希望确定我的可执行文件中的哪个调用目标地址对应于symbol_iterator通过调用该begin_dynamic_symbols()函数获得的符号名称.迭代每个符号symbol_iterator给出了每个符号的名称及其地址,但由于符号是动态的,因此每个符号的地址为-1; 这表示ObjectFile不会将符号名称直接与其对应的呼叫目标地址相关联.
有没有办法确定哪个呼叫目的地地址映射到哪个动态符号ObjectFile?我宁愿不手动计算所有的跳跃PLT,GOT如果我可以避免这样做.
我写了一个传递来检测和打印函数中基本块的标签,因为我想splitBasicBlock()进一步使用.我写的是这样的:
virtual bool runOnModule(Module &M)
{
for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{
errs()<<"Function:"<<F->getName()<<"\n";
//for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (iplist<BasicBlock>::iterator iter = F->getBasicBlockList().begin();
iter != F->getBasicBlockList().end();
iter++)
{
BasicBlock* currBB = iter;
errs() << "BasicBlock: " << currBB->getName() << "\n";
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
IR文件如下所示:
; <label>:63 ; preds = %43
%64 = load i32* %j, align 4
%65 = sext i32 %64 to i64
%66 …Run Code Online (Sandbox Code Playgroud) 我发现很难理解LLVM C++ API.我想问你一下吗?LLVM C++ API和LLVM IR之间有什么关系吗?另外,我想知道如何使用LLVM C++ API?
我有一个使用opt工具的ModulePass,但是我无法弄清楚如何在命令行中使用它.我目前使用my pass的工作流程是:
我希望将我的pass与clang命令行集成,以便可以作为现有软件(例如c ++标准库)构建的一部分调用它,而不必为我编译的每个东西重新构建整个构建系统.我已经看到了关于如何做到这一点的提示,但我无法将各个部分组合到一个正常工作的设置中.
使用Clang自动运行LLVM Pass会自动描述我想要的内容,但LLVM 3.4中似乎不推荐使用该方法(PassManagerBuilder已移至旧版命名空间).
LLVM - 使用clang自动运行自己的通行证似乎解决了基本问题,但我希望我能做到这一点,而不必修改clang(这似乎是那里的建议).
使用LLVM 3.4从clang获得新传递的最佳方法是什么?
我有ConstantInt和ConstantFP想要添加的值fadd.但是,我无法将其ConstantInt转换为fadd可接受的浮点数.
以下是代码的摘录:
Value* left = ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 12, true);
Value* right = ConstantFP::get(Type::getFloatTy(getGlobalContext()), 11.6);
Instruction* cast = CastInst::Create(Instruction::SIToFP, left, left->getType(), "", currentBlock());
left = cast->getOperand(0);
BinaryOperator::Create(Instruction::FAdd, left, right, "", currentBlock());
Run Code Online (Sandbox Code Playgroud)
哪里currentBlock()返回一个BasicBlock.在尝试为此生成操作码之后,LLVM抱怨它无法添加这两个值,因为它们不相同.
我对LLVM很新,所以如果这段代码没有意义,我会接受任何建议.
LLVM中的comdat代表什么?您可以在这里找到来源:Comdata
源级程序表示(c++)的示例将非常有帮助。
如果您需要更多信息,请随时询问。我在 llvm 代码库的很多地方找到它,但我无法弄清楚它到底是什么,以及它的用途
感谢您的帮助!