标签: clang++

从函数获取文件名和位置

我有一个遍历 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)

但是,由于类FunctionBasicBlock没有成员函数getDebugLoc(),这不起作用。我在这里看到了另一篇使用元数据的帖子但我不知道如何访问元数据DILocationDIScope从元数据获取。使用

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)

llvm llvm-clang clang++ llvm-3.0 llvm-ir

1
推荐指数
1
解决办法
1458
查看次数

clang:折叠表达式和"表达结果未使用"警告

在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很满意.

c++ templates variadic-templates clang++ c++17

1
推荐指数
1
解决办法
182
查看次数

为什么 constexpr 上下文会使编译器失败,而它却无法完美优化?

我尝试了一下constexpr并发现了一些有趣的行为:

  • 在某些情况下,constexpr在函数前面添加使GCC能够尝试更努力地优化,从而导致完全优化函数并仅提供计算值。
  • 然而,从上下文中调用这样一个完全优化的函数constexpr会导致错误,因为它内部使用了未标记的constexpr(特别是)函数/内部函数(编译器内置memcpy)。
  • (当应用到这样的函数时,即使没有上下文, Clang也会直接失败。)constexprconstexpr

为什么会这样?

  • 即使在上下文中,编译器(GCC)不应该仍然能够优化吗constexpr
  • C++ 提案P0202(将其纳入 C++20)想要创建类似的函数memcpy constexpr(请参阅原始修订版中的第III.B节),但这被拒绝并更改,因为此类函数的编译器内置版本将实现相同的功能(请参阅最新修订版中的第 III.A节)。
  • 那么,GCCClang不允许memcpyconstexpr函数/上下文中使用是错误的吗?(注: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++ g++ compiler-optimization clang++ c++20

1
推荐指数
1
解决办法
662
查看次数

为什么在类中声明为对象的成员变量的地址值总是变化?在 C++

我正在研究 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)

c++ class clang member-variables clang++

1
推荐指数
1
解决办法
65
查看次数

clang++ 编译无法访问的函数,g++ 则不会

我在 Instagram 上看到了这个表情包,内容是关于一些 C++ 代码,这些代码不应该输出任何内容,但却输出了任何内容。代码是:

#include <iostream>

int main() {
    while (1)
        ;
}

void unreachable() {
    std::cout << "Hello World!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

c++meme 发布

我用 clang 编译了它,如 meme 中所示,并得到了相同的结果 ( Ubuntu clang version 14.0.0-1ubuntu1.1),但使用 gcc 编译的相同代码执行了您所期望的操作:什么都没有 ( g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0)。

我想知道为什么 clang 会做不同的事情,以及如果我从不从主函数调用它,那么如何破解无法访问的函数是如何执行的。

c++ g++ clang++

1
推荐指数
1
解决办法
544
查看次数

这个行数在这个错误中意味着什么?

编译一些代码时,我收到如下错误:

endpointer.h:88:24: error: expected ‘)’ before ‘*’ token

什么:88:24意思?

c++ g++ build clang++

0
推荐指数
1
解决办法
136
查看次数

虚函数的继承

我有以下代码.

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)

c++ inheritance virtual-functions c++11 clang++

0
推荐指数
2
解决办法
148
查看次数

使用-std = gnu ++ 11编译clang ++失败

我正在尝试通过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)

clang c++11 clang++

0
推荐指数
1
解决办法
756
查看次数

std :: vector operator []的行为不正确

我有下一个代码片段.我的想法是,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++ vector std clang clang++

0
推荐指数
1
解决办法
144
查看次数

理解clang在汇编中做了什么,递减递增的循环

在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.1clang++ 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)

c++ assembly increment compiler-optimization clang++

0
推荐指数
1
解决办法
100
查看次数