我有一个遍历 LLVM IR 代码的 LLVM 传递,我想为原始代码的函数和基本块获取一个目录和一个文件名。我知道当我有一个指令指针时,我可以使用下面的代码轻松获取信息:感谢@hailinzeng(如何从 LLVM 指令获取文件名和目录?)
const llvm::DebugLoc &location = i_iter->getDebugLoc();
if (location && debugLocationInfoOn) {
std::string dbgInfo;
llvm::raw_string_ostream rso(dbgInfo);
location.print(rso);
std::cout << rso.str();
}
Run Code Online (Sandbox Code Playgroud)
但是,由于类Function和BasicBlock没有成员函数getDebugLoc(),这不起作用。我在这里看到了另一篇使用元数据的帖子,但我不知道如何访问元数据DILocation或DIScope从元数据获取。使用
MDNode *n = inst->getMetadata("dbg");
DILocation loc(n); `
Run Code Online (Sandbox Code Playgroud)
给出以下错误
/usr/lib/llvm-3.9/include/llvm/IR/Metadata.def:83:42: 注意:'llvm::DILocation' 的前向声明 HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)
我正在使用 llvm 3.9。
更新 :: 感谢斯坦尼斯拉夫·潘克维奇。我没有包含正确的标题,但现在我有一个新问题。DILocation 需要 LLVMContext、StorageType 和 unsigned Line。如何从函数指针获取行号和存储类型?
DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
对于那些处理类似问题的人,您可以使用 LLVMContext
llvm::MDNode * testmd = F.getMetadata("dbg"); …Run Code Online (Sandbox Code Playgroud) 在clang 7.0上这段代码:
template <typename ... Ts> struct S {
unsigned gs(unsigned i) {
unsigned r = 0;
((r = unsigned(sizeof(Ts)), i-- == 0) || ...);
return r;
}
};
int foo(unsigned i) {
S<int, double, long, float, char> s;
return s.gs(3);
}
Run Code Online (Sandbox Code Playgroud)
导致此警告:
~/dev/ta $ ~/bin/clang++ -c -std=c++17 fold-warning.cpp
fold-warning.cpp:5:46: warning: expression result unused [-Wunused-value]
((r = unsigned(sizeof(Ts)), i-- == 0) || ...);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
Run Code Online (Sandbox Code Playgroud)
为什么?编译器的逻辑是什么表达式未被使用?
Gcc 7.3/8.2很满意.
我尝试了一下constexpr并发现了一些有趣的行为:
constexpr在函数前面添加使GCC能够尝试更努力地优化,从而导致完全优化函数并仅提供计算值。constexpr会导致错误,因为它内部使用了未标记的constexpr(特别是)函数/内部函数(编译器内置memcpy)。constexprconstexpr为什么会这样?
constexpr?memcpy constexpr(请参阅原始修订版中的第III.B节),但这被拒绝并更改,因为此类函数的编译器内置版本将实现相同的功能(请参阅最新修订版中的第 III.A节)。memcpy在constexpr函数/上下文中使用是错误的吗?(注:memcpy和__builtin_memcpy是等效的。)为了更容易理解,这里举个例子。(您甚至可以在此处的Compiler Explorer
中更轻松地查看其结果。)
注意:我无法想出一个简单的例子,其中简单地添加constexpr到函数中就可以帮助GCC优化器完全优化,否则它不会。但相信我,我有这样的例子,它们更复杂(遗憾的是闭源)。
#include <array>
#include <cstdint>
#include <cstring>
constexpr std::uint32_t extract(const std::uint8_t* data) noexcept
{ …Run Code Online (Sandbox Code Playgroud) 我正在研究 C++ 类。我正在编写一个名为 User 的类。成员变量被声明为类中的对象。返回此对象地址的函数是 getAddr()。为了您的信息,getAddr() 函数也存在于 User 类中。
我在打印用户对象和用户对象中的人物对象的地址值时发现了一些奇怪的东西。发现每次调用getAddr()都会改变User对象中Person对象的地址值。
我写的代码如下。
#include <iostream>
#include <sstream>
class Person {
private:
int num;
public:
Person(){};
std::string getAddr() {
std::stringstream ss;
ss << this;
return (ss.str());
}
};
class User {
private:
Person _person;
Person *_ptr_person;
public:
User() {
this->_ptr_person = new Person();
this->_person = Person();
}
std::string getAddr() {
std::stringstream ss;
ss << this;
return (ss.str());
}
Person *getPtrPerson() {
return this->_ptr_person;
}
Person getPerson() {
return this->_person;
}
~User() {
delete …Run Code Online (Sandbox Code Playgroud) 我在 Instagram 上看到了这个表情包,内容是关于一些 C++ 代码,这些代码不应该输出任何内容,但却输出了任何内容。代码是:
#include <iostream>
int main() {
while (1)
;
}
void unreachable() {
std::cout << "Hello World!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我用 clang 编译了它,如 meme 中所示,并得到了相同的结果 ( Ubuntu clang version 14.0.0-1ubuntu1.1),但使用 gcc 编译的相同代码执行了您所期望的操作:什么都没有 ( g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0)。
我想知道为什么 clang 会做不同的事情,以及如果我从不从主函数调用它,那么如何破解无法访问的函数是如何执行的。
编译一些代码时,我收到如下错误:
endpointer.h:88:24: error: expected ‘)’ before ‘*’ token
什么:88:24意思?
我有以下代码.
class A {
public:
virtual void foo() = 0;
}
class B : public A {
public:
void bar() { /* Do something */ }
}
void B::A::foo() {
bar();
// Do something else
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译这个...我得到一个错误,说它无法找到bar().这不是实例化纯虚函数的正确方法吗?
use of undeclared identifier 'bar'
Run Code Online (Sandbox Code Playgroud) 我正在尝试通过clang ++ 3.4版编译我的项目.我使用标志-std = gnu ++ 11,它失败了.
早些时候我使用llvm 3.3,一切都很好.但现在我有这样的错误信息:
clang (LLVM option parsing): Unknown command line argument '-std=gnu++11'. Try: 'clang (LLVM option parsing) -help'
clang (LLVM option parsing): Did you mean '-stats=gnu++11'?
Run Code Online (Sandbox Code Playgroud) 我有下一个代码片段.我的想法是,vector有5个项目,我通过operator []访问100,这应该会导致崩溃.但正如你在输出中看到的那样,它有效.
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec(5, 1);
vec[100] = 25;
std::cout << "vec[100] = " << vec[100] << ", vec[99] = " << vec[99] <<
", vector size = " << vec.size() <<
", vector capacity = " << vec.capacity() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
vec[100] = 25, vec[99] = 0, vector size = 5, vector capacity = 5
Run Code Online (Sandbox Code Playgroud)
编译标志:
clang++ -W -Wall -std=c++14 -stdlib=libc++ vector_over_flow_test.cpp -o vector_overflow_test.bin
Run Code Online (Sandbox Code Playgroud)
铿锵版:
$clang++ --version
Apple LLVM version 8.0.0 (clang-800.0.42.1) …Run Code Online (Sandbox Code Playgroud) 在C++中考虑以下代码:
#include <cstdlib>
std::size_t count(std::size_t n)
{
std::size_t i = 0;
while (i < n) {
asm volatile("": : :"memory");
++i;
}
return i;
}
int main(int argc, char* argv[])
{
return count(argc > 1 ? std::atoll(argv[1]) : 1);
}
Run Code Online (Sandbox Code Playgroud)
它只是一个递增其值的循环,并在最后返回它.所述asm volatile防止环路它被优化.我们编译下g++ 8.1和clang++ 5.0与争论-Wall -Wextra -std=c++11 -g -O3.
现在,如果我们看一下编译器资源管理器正在生成什么,我们有g++:
count(unsigned long):
mov rax, rdi
test rdi, rdi
je .L2
xor edx, edx
.L3:
add rdx, 1
cmp rax, …Run Code Online (Sandbox Code Playgroud)