7

この C++ コードのスニペットをコンパイルしようとしました。

void FuncTest() {
    int* a = new int;
    int* b = new int[2];
}

使用:

clang test.cpp -S -emit-llvm -o - > test.llvm

そして、これを得ました:

define void @_Z8FuncTestv() {
entry:
  %a = alloca i32*, align 4
  %b = alloca i32*, align 4
  %call = call noalias i8* @_Znwj(i32 4)
  %0 = bitcast i8* %call to i32*
  store i32* %0, i32** %a, align 4
  %call1 = call noalias i8* @_Znaj(i32 8)
  %1 = bitcast i8* %call1 to i32*
  store i32* %1, i32** %b, align 4
  ret void
}

declare noalias i8* @_Znwj(i32)
declare noalias i8* @_Znaj(i32)

私が今疑問に思っているのは、記号_Znwj_Znaj記号はどこから来たのかということです。それらはランダムに割り当てられているだけですか、それともシステムがありますか? 次の行を伝えたいと思います。

%call = call noalias i8* @_Znwj(i32 4)

%call1 = call noalias i8* @_Znaj(i32 8)

メモリ割り当てを実行します。しかし、それほど有望ではないようです。

アイデアを持っているllvmの専門家はいますか?

4

2 に答える 2

5

オペレーターの C++ マングル名が表示されています。abi::__cxa_demangleを使用してシンボルをデマングルするか、マングルされたシンボルのテーブルを作成します。new/delete 演算子はオーバーロードされている可能性があるため、シンボルは一定ではありません。デマングリングが最も安全なオプションかもしれません。

これは c++filt を介してパイプされた関数で、abi::__cxa_demangleを使用します。

void @FuncTest()() を定義する {
エントリ:
  %a = alloca i32*、アライン 4
  %b = alloca i32*、アライン 4
  %call = call noalias i8* @operator new(unsigned int)(i32 4)
  %0 = ビットキャスト i8* %i32 への呼び出し*
  i32* %0 を保存、i32** %a、整列 4
  %call1 = コール noalias i8* @operator new[](unsigned int)(i32 8)
  %1 = ビットキャスト i8* %call1 から i32*
  i32* %1 を格納、i32** %b、アライン 4
  ret void
}

宣言 noalias i8* @operator new(unsigned int)(i32)
宣言 noalias i8* @operator new[](unsigned int)(i32)
于 2010-10-22T05:56:23.087 に答える