clang llvm промежуточное представление для отладочной информации - PullRequest
0 голосов
/ 09 августа 2011

Здравствуйте, у меня следующий код c ++

<code>
class classBase
{
public:
    int get1(){return 1;}
    int get2(){return 2;}
};
class classDer:public classBase
{
public:
    int get1(){return 1;}
};</p>

<p>int f()
{
    classDer x;
    return x.get1();
}
Я использую следующую команду clangExample.cpp -S -emit-llvm -o - и получаю
; ModuleID = 'C:\clangParam\clangExample.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i686-pc-win32"

%class.classDer = type { i8 }

define i32 @_Z1fv() {
entry:
  %x = alloca %class.classDer, align 1
  %call = call i32 @_ZN8classDer4get1Ev(%class.classDer* %x)
  ret i32 %call
}

define linkonce_odr i32 @_ZN8classDer4get1Ev(%class.classDer* %this) nounwind align 2 {
entry:
  %this.addr = alloca %class.classDer*, align 4
  store %class.classDer* %this, %class.classDer** %this.addr, align 4
  %this1 = load %class.classDer** %this.addr
  ret i32 1
}

почему нет ссылки на базовый класс? (Переходя через код лязг для типаПоколение У меня возникло ощущение, что на базовый класс следует ссылаться.

Обновление Это имеет смысл Но если я использую определение шаблона

template<class T>
class classTemplate
{
public:
    T getMax(T in1,T in2){if(in2 > in1) return in2;return in1;}
};

int f()
{
    classTemplate<int> x;
    return x.getMax(3,4);
}

, я получаю вывод clang

C:\Windows\system32>clang C:\clangParam\clangExample.cpp -S -emit-llvm -o -
; ModuleID = 'C:\clangParam\clangExample.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i686-pc-win32"

%class.classTemplate = type { i8 }

define i32 @_Z1fv() {
entry:
  %x = alloca %class.classTemplate, align 1
  %call = call i32 @_ZN13classTemplateIiE6getMaxEii(%class.classTemplate* %x, i32 3, i32 4)
  ret i32 %call
}

define linkonce_odr i32 @_ZN13classTemplateIiE6getMaxEii(%class.classTemplate* %this, i32 %in1, i32 %in2) nounwind align 2 {
entry:
  %retval = alloca i32, align 4
  %this.addr = alloca %class.classTemplate*, align 4
  %in1.addr = alloca i32, align 4
  %in2.addr = alloca i32, align 4
  store %class.classTemplate* %this, %class.classTemplate** %this.addr, align 4
  store i32 %in1, i32* %in1.addr, align 4
  store i32 %in2, i32* %in2.addr, align 4
  %this1 = load %class.classTemplate** %this.addr
  %tmp = load i32* %in2.addr, align 4
  %tmp2 = load i32* %in1.addr, align 4
  %cmp = icmp sgt i32 %tmp, %tmp2
  br i1 %cmp, label %if.then, label %if.end

if.then:                                          ; preds = %entry
  %tmp3 = load i32* %in2.addr, align 4
  store i32 %tmp3, i32* %retval
  br label %return

if.end:                                           ; preds = %entry
  %tmp4 = load i32* %in1.addr, align 4
  store i32 %tmp4, i32* %retval
  br label %return

return:                                           ; preds = %if.end, %if.then
  %0 = load i32* %retval
  ret i32 %0
}

Опять нет ссылки на класс шаблона, хотя я его инициализирую.

Ответы [ 2 ]

2 голосов
/ 10 августа 2011

Причина, по которой он не экспортируется и даже не компилируется, заключается в том, что функции внутри объявлений классов являются встроенными.Это означает, что они известны и скомпилированы только внутри этого конкретного файла кода.

Если вы поместите объявление класса в файл заголовка, каждый файл .cpp скомпилирует код для функций get1 () и get2 () отдельно(поэтому он будет присутствовать дважды в конечном исполняемом файле).

ClassBase :: get1 () и ClassBase :: get2 () никогда не ссылаются, и поэтому они не учитываются.То же самое относится и к возможности перегрузки классов: компилятор знает, что нет никаких производных ни от одного из классов, потому что он видит все, что только может быть.

1 голос
/ 10 августа 2011

Почему вы ожидаете отладочную информацию без передачи -g? Это выводит много узлов метаданных:

// clang++ -g3 -S -emit-llvm main1.cpp
// ...

!0 = metadata !{i32 589841, i32 0, i32 4, metadata !"main1.cpp", metadata !"/home/js/cpp", metadata !"clang version 3.0 (trunk 134121)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"f", metadata !"f", metadata !"_Z1fv", metadata !2, i32 16, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 ()* @_Z1fv, null, null} ; [ DW_TAG_subprogram ]
!2 = metadata !{i32 589865, metadata !"main1.cpp", metadata !"/home/js/cpp", metadata !0} ; [ DW_TAG_file_type ]
!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!4 = metadata !{metadata !5}
!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
!6 = metadata !{i32 589870, i32 0, metadata !7, metadata !"get1", metadata !"get1", metadata !"_ZN9classBase4get1Ev", metadata !2, i32 5, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ]
!7 = metadata !{i32 589826, metadata !0, metadata !"classBase", metadata !2, i32 2, i64 8, i64 8, i32 0, i32 0, null, metadata !8, i32 0, null, null} ; [ DW_TAG_class_type ]
!8 = metadata !{metadata !6, metadata !9, metadata !13}
!9 = metadata !{i32 589870, i32 0, metadata !7, metadata !"get2", metadata !"get2", metadata !"_ZN9classBase4get2Ev", metadata !2, i32 6, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ]
!10 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !11, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!11 = metadata !{metadata !5, metadata !12}
!12 = metadata !{i32 589839, metadata !0, metadata !"", i32 0, i32 0, i64 32, i64 32, i64 0, i32 64, metadata !7} ; [ DW_TAG_pointer_type ]
!13 = metadata !{i32 589870, i32 0, metadata !7, metadata !"classBase", metadata !"classBase", metadata !"", metadata !2, i32 2, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ]
!14 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !15, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!15 = metadata !{null, metadata !12}
!16 = metadata !{i32 589870, i32 0, metadata !17, metadata !"get1", metadata !"get1", metadata !"_ZN8classDer4get1Ev", metadata !2, i32 11, metadata !24, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ]
!17 = metadata !{i32 589826, metadata !0, metadata !"classDer", metadata !2, i32 8, i64 8, i64 8, i32 0, i32 0, null, metadata !18, i32 0, null, null} ; [ DW_TAG_class_type ]
!18 = metadata !{metadata !19, metadata !16, metadata !20}
!19 = metadata !{i32 589852, metadata !17, null, metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !7} ; [ DW_TAG_inheritance ]
!20 = metadata !{i32 589870, i32 0, metadata !17, metadata !"classDer", metadata !"classDer", metadata !"", metadata !2, i32 8, metadata !21, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ]
!21 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !22, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!22 = metadata !{null, metadata !23}
!23 = metadata !{i32 589839, metadata !0, metadata !"", i32 0, i32 0, i64 32, i64 32, i64 0, i32 64, metadata !17} ; [ DW_TAG_pointer_type ]
!24 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !25, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!25 = metadata !{metadata !5, metadata !23}
!26 = metadata !{i32 589870, i32 0, metadata !0, metadata !"get1", metadata !"get1", metadata !"_ZN8classDer4get1Ev", metadata !2, i32 11, metadata !24, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 (%class.classDer*)* @_ZN8classDer4get1Ev, null, metadata !16} ; [ DW_TAG_subprogram ]
!27 = metadata !{i32 590080, metadata !28, metadata !"x", metadata !2, i32 17, metadata !17, i32 0} ; [ DW_TAG_auto_variable ]
!28 = metadata !{i32 589835, metadata !1, i32 16, i32 1, metadata !2, i32 0} ; [ DW_TAG_lexical_block ]
!29 = metadata !{i32 17, i32 14, metadata !28, null}
!30 = metadata !{i32 18, i32 5, metadata !28, null}
!31 = metadata !{i32 590081, metadata !26, metadata !"this", metadata !2, i32 16777227, metadata !23, i32 64} ; [ DW_TAG_arg_variable ]
!32 = metadata !{i32 11, i32 9, metadata !26, null}
!33 = metadata !{i32 11, i32 16, metadata !34, null}
!34 = metadata !{i32 589835, metadata !26, i32 11, i32 15, metadata !2, i32 1} ; [ DW_TAG_lexical_block ]

Ищите теги типа класса, вы найдете

!7 = metadata !{i32 589826, metadata !0, metadata !"classBase", metadata !2, i32 2, i64 8, i64 8, i32 0, i32 0, null, metadata !8, i32 0, null, null} ; [ DW_TAG_class_type ]
!17 = metadata !{i32 589826, metadata !0, metadata !"classDer", metadata !2, i32 8, i64 8, i64 8, i32 0, i32 0, null, metadata !18, i32 0, null, null} ; [ DW_TAG_class_type ]
...