当我访问一个声明(在 Clang 库中)时,如何获取写入Decl该声明的文件的名称?Decl
有一个FileData类,但我找不到任何其他类可以让我得到这个FileData
Clang 的文档说“默认情况下,MemorySanitizer 在第一次检测到错误时退出”。
有人知道如何使 MemorySanitizer 不因错误而停止吗?上面这句话表明有一种方法,但我在文档中没有找到任何内容。
我正在从源代码构建 clang,但使用不在正常位置的 gcc 7.2 构建。我希望生成的clang++二进制文件默认使用此工具链。我尝试这样做:
$ export GCC_PREFIX=/path/to/gcc/7.2
$ mkdir -p build
$ cd build
$ cmake -G Ninja -DCMAKE_C_COMPILER=${GCC_PREFIX}/bin/gcc \
-DCMAKE_CXX_COMPILER=${GCC_PREFIX}/bin/g++ \
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_TARGETS_TO_BUILD=X86 ..
Run Code Online (Sandbox Code Playgroud)
但生成的构建只是查找/usr/include/c++/4.8.5标准库包含而不是像/path/to/gcc/7.2/include我想要的那样(并且,正如路径所示,4.8.5 有点旧)。有没有办法构建 clang,以便生成的二进制文件将搜索我想要的包含目录的路径?
注意,我知道我使用 运行生成的二进制文件--gcc-toolchain=${GCC_PREFIX}。这样可行。我想做的是将其构建到二进制文件中,这样我就不必每次都输入它。
我正在尝试在 Mac 上设置 vulkan/MoltenVk,但在验证层和扩展工作时遇到一些问题。
我已经下载/安装了 MoltenVk 和 vulkan 库,设置了一些环境变量:
export VULKAN_SDK=/opt/vulkan-sdk
export DYLD_LIBRARY_PATH=$VULKAN_SDK/lib:$DYLD_LIBRARY_PATH
export VK_ICD_FILENAMES=$VULKAN_SDK/etc/vulkan/icd.d/MoltenVK_icd.json
export VK_LAYER_PATH=$VULKAN_SDK/etc/vulkan/explicit_layer.d
export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_standard_validation
Run Code Online (Sandbox Code Playgroud)
vulkaninfo 按预期工作并显示 6 个验证层。
当我尝试构建自己的项目时,它找不到图层。
我创建了一个小型测试项目来尝试弄清楚发生了什么。它编译和链接没有错误,但是当我运行它时,我得到
[***MoltenVK ERROR***] VK_ERROR_LAYER_NOT_PRESENT: Vulkan layer VK_LAYER_LUNARG_standard_validation is not supported.
vkCreateInstance result: -6
Run Code Online (Sandbox Code Playgroud)
main.cpp (复制自https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)
#include <iostream>
#include <vulkan/vulkan.h>
int main(int argc, const char * argv[]) {
VkInstance instance;
VkResult result;
VkInstanceCreateInfo info = {};
uint32_t instance_layer_count;
result = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
std::cout << instance_layer_count << " layers found!\n";
if (instance_layer_count > 0) {
std::unique_ptr<VkLayerProperties[]> …Run Code Online (Sandbox Code Playgroud) 我有以下代码示例(可在coliru在线获取):
#include <iostream>
#include <utility>
struct Bar {
int a;
};
template <class T>
void print_arg(const T& arg) {
std::cout << arg << std::endl;
}
std::ostream& operator<<(std::ostream& os, const Bar& b) {
os << b.a;
return os;
}
template <class T1, class T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& pair) {
os << "Pair(" << pair.first << ',' << pair.second << ")";
return os;
}
int main()
{
auto bar = Bar{1};
print_arg(bar);
print_arg(std::make_pair(bar, bar));
print_arg(std::make_pair(bar, 1));
print_arg(std::make_pair(0, …Run Code Online (Sandbox Code Playgroud) 所以我在 mac 上想要尝试最新的 llvm 版本,而不必等待它们在 xcode 命令行工具上传递。
因此,我从他们的下载页面下载了 LLVM 10 版本的预构建二进制文件,并将其放在名为 llvm 的文件夹中。因此,可以在 ~/SDKs/LLVM/bin 中找到 clang 可执行文件。
我制作这个程序:
#include <string>
#include <iostream>
int main(int argc, char const *argv[])
{
std::string myString("Hello World");
std::cout << myString;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并运行:
~/SDKs/Clang+LLVM10/bin/clang++ main.cpp
Run Code Online (Sandbox Code Playgroud)
我收到这个致命错误:
~/SDKs/Clang+LLVM10/bin/../include/c++/v1/string.h:60:15: fatal error:
'string.h' file not found
#include_next <string.h>
^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这没有意义,因为我可以使用 finder 手动找到 string.h,并且它就在错误中引用的文件夹中。
我猜这与 clang++ 首先搜索我的系统包含路径有关,在那里找到旧的 string.h ,因此选择不使用更新的 string.h ,从而导致错误?
一些附加信息(如果有帮助的话):
运行这个(新编译器)
~/Programming/SDKs/Clang+LLVM10/bin/clang++ -Wp,-v -E -xc -x c++ /dev/null
Run Code Online (Sandbox Code Playgroud)
给我:
clang -cc1 version 10.0.0 based upon LLVM …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过阅读 LLVM 文档来创建一种新的编程语言。其中一个文档是关于“Kaleidscope”的,这是一种玩具编程语言。(教程在这里: https: //releases.llvm.org/9.0.0/docs/tutorial/LangImpl01.html)。
教程中的所有代码都写在一个文件中,可以通过以下命令进行编译:
clang++ -g -O3 toy.cpp -I/usr/lib/llvm-10/include -std=c++14 \
-fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \
-L/usr/lib/llvm-10/lib \
-rdynamic \
-lLLVM-10 -o toy
Run Code Online (Sandbox Code Playgroud)
但是,我想通过 CMake 管理我的项目。CMakeLists.txt除了选项“-rdynamic”之外,我已将上面的大部分命令翻译成一个文件(随后附加)。有谁知道如何将此选项添加到我的CMakeLists.txt?提前致谢!
SET(CMAKE_CXX_COMPILER "/usr/bin/clang++")
INCLUDE_DIRECTORIES("/usr/lib/llvm-10/include")
LINK_DIRECTORIES("/usr/lib/llvm-10/lib")
SET(_GNU_SOURCE 1)
SET(__STDC_CONSTANT_MACROS 1)
SET(__STDC_FORMAT_MACROS 1)
SET(__STDC_LIMIT_MACROS 1)
# Project configuration
# omit something unrelated
FIND_PACKAGE(LLVM REQUIRED CONFIG)
TARGET_LINK_LIBRARIES(compiler LLVM-10)
Run Code Online (Sandbox Code Playgroud) 在 C++ 中,函数模板的类型检查被推迟到调用(实例化)模板函数为止。例如
template<typename T>
int right() {
return T::f();
}
Run Code Online (Sandbox Code Playgroud)
是合法的 C++ 代码,之后right<Foo>()只要 typeFoo具有f返回int.
我观察到我的 C++ 编译器 (Clang) 可以捕获一些类型错误,只要它们不依赖于模板参数即可。例如
template<typename T>
int wrong1() {
return "";
}
Run Code Online (Sandbox Code Playgroud)
即使从未调用(实例化)模板函数,也无法使用 Clang 16.0.0 进行编译(char*与 不兼容)。int这就带来了一个问题:C++ 编译器是否要求模板函数声明类型正确(忽略依赖于模板参数的表达式)?或者它只是 Clang 的一个功能,它试图尽早捕获类型错误?
以下代码在 g++、clang 和 Visual Studio 上编译:
#define HEX(hex_) 0x##hex_
int main()
{
return HEX(BadC0de);
}
Run Code Online (Sandbox Code Playgroud)
与此修改一样,使用 C++14 数字分隔符:
return HEX(1'Bad'C0de);
Run Code Online (Sandbox Code Playgroud)
但这不能在 g++ 或 clang 上编译(它可以在 Visual Studio 上运行):
#define HEX(hex_) 0x##hex_
int main()
{
return HEX(A'Bad'C0de);
}
Run Code Online (Sandbox Code Playgroud)
g++ 输出:
<source>:4:1: warning: multi-character character constant [-Wmultichar]
4 | return HEX(A'Bad'C0de);
| ^
<source>: In function 'int main()':
<source>:4:17: error: expected ';' before user-defined character literal
4 | return HEX(A'Bad'C0de);
| ^~~~~~~~~
<source>:1:25: note: in definition of macro 'HEX'
1 | #define …Run Code Online (Sandbox Code Playgroud) 我有一个与下面的代码片段非常相似的代码:
#include <vector>
struct dummy
{
std::vector<int> const data;
dummy() = default;
};
Run Code Online (Sandbox Code Playgroud)
大多数编译器都毫无问题地接受此代码,但clang版本 9 至 14 除外:
警告:显式默认的默认构造函数被隐式删除 [-Wdefaulted-function-deleted]
注意:“dummy”的默认构造函数被隐式删除,因为 const 限定类型“const std::vector”的字段“data”不会被初始化
问题clang 15再次消失。
居住
注意,如果const删除,错误也会消失。
然而我希望data被初始化为一个const空向量。
这是一个clang错误吗?否则,为什么这段代码被拒绝(为什么其他编译器不抱怨)?