我已经阅读了有关dumping a C++ object's memory layout with Clang的文章,现在我正在尝试使用此功能。我创建了两个类:
// simple.cpp
struct Base
{
int value;
};
struct Derived : Base
{
int count;
};
int main(int argc, char* argv[])
{
return 0;
}
并运行以下命令:
$ clang -cc1 -fdump-record-layouts-simple simple.cpp
却什么也没得到。 lang版本是:
$ clang++ -dumpversion
4.2.1
如果我运行以下命令:
$ clang -cc1 --help
在很多信息中,我可以找到这一点:
...
-fdump-record-layouts-simple
Dump record layout information in a simple form used for testing
-fdump-record-layouts Dump record layout information
-fdump-vtable-layouts Dump the layouts of all vtables that will be emitted in a translation unit
...
我做错了什么?
答案 0 :(得分:3)
您需要进行两项更改:
def tokenize_finditer(line):
token_pat = re.compile(r'({{)|(}})')
result = []
if re.search(token_pat, line):
prev = len(line)
for match in re.finditer(token_pat, line):
start, end = match.span()
if start > prev:
expr = line[prev:start]
if not expr.isspace():
result.append(expr)
prev = end
result.append(match.group())
return result
编译器开关。没有这个,就不需要LLVM输出,因此永远不会计算记录布局,也不会转储。进行这些更改后,将这样的输出打印在stdout上:
-emit-llvm
...
*** Dumping AST Record Layout
Type: struct Base
Layout: <ASTRecordLayout
Size:32
DataSize:32
Alignment:32
FieldOffsets: [0]>
*** Dumping AST Record Layout
Type: struct Derived
Layout: <ASTRecordLayout
Size:64
DataSize:64
Alignment:32
FieldOffsets: [32]>
答案 1 :(得分:1)
这是根据我对clang 10.0.1的经验所做的更新:
一个必要条件是,编译器需要一些理由来实际关心所讨论结构的布局。因此,原始问题中的simple.cpp
源文件似乎永远不会导致转储。我发现添加代码以实例化这些结构之一,或在其上调用sizeof(...)
,或调用其虚拟方法之一,都可以。
如果您使用的是-cc1
,则需要-emit-llvm
或 -emit-obj
引起转储。 (也许其他选项也可以,但是在我的实验中,我至少需要其中一种。)
如果您不想使用-cc1
选项(也许是因为您只是想将它们添加到假定具有g ++兼容性的现有构建系统中),这样的调用也可以:{{ 1}}。 (至少在我的系统上,这种方法的好处是,以这种方式调用clang会导致结构布局信息在我的终端中着色。)
我上面写的内容似乎也适用于clang -Xclang -fdump-record-layouts-simple simple.cpp
和-fdump-record-layouts
选项。