Hi, I’m new to LLVM and try to get help here. I would like to write a LLVM pass to do some analysis, but not sure if I can get the information that the class a function belongs to. For example:
#include <cstdio>
class Animal {
public:
int id;
int report_id() {
return id;
}
void change_id(int m) {
id = m;
}
Animal(int x) {
id = x;
}
};
int main() {
Animal* a = new Animal(653);
int w = a->report_id();
printf("%d\n", w);
a->change_id(322);
w = a->report_id();
printf("%d\n", w);
return 0;
}
lowers to LLVM IR:
define dso_local i32 @main() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg !206 {
%1 = alloca i32, align 4
%2 = alloca %class.Animal*, align 8
%3 = alloca i8*, align 8
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
call void @llvm.dbg.declare(metadata %class.Animal** %2, metadata !207, metadata !DIExpression()), !dbg !220
%6 = call noalias nonnull i8* @_Znwm(i64 4) #7, !dbg !221, !heapallocsite !209
%7 = bitcast i8* %6 to %class.Animal*, !dbg !221
invoke void @_ZN6AnimalC2Ei(%class.Animal* nonnull dereferenceable(4) %7, i32 653)
to label %8 unwind label %18, !dbg !222
8: ; preds = %0
store %class.Animal* %7, %class.Animal** %2, align 8, !dbg !220
call void @llvm.dbg.declare(metadata i32* %5, metadata !223, metadata !DIExpression()), !dbg !224
%9 = load %class.Animal*, %class.Animal** %2, align 8, !dbg !225
%10 = call i32 @_ZN6Animal9report_idEv(%class.Animal* nonnull dereferenceable(4) %9), !dbg !226
store i32 %10, i32* %5, align 4, !dbg !224
%11 = load i32, i32* %5, align 4, !dbg !227
%12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %11), !dbg !228
%13 = load %class.Animal*, %class.Animal** %2, align 8, !dbg !229
call void @_ZN6Animal9change_idEi(%class.Animal* nonnull dereferenceable(4) %13, i32 322), !dbg !230
%14 = load %class.Animal*, %class.Animal** %2, align 8, !dbg !231
%15 = call i32 @_ZN6Animal9report_idEv(%class.Animal* nonnull dereferenceable(4) %14), !dbg !232
store i32 %15, i32* %5, align 4, !dbg !233
%16 = load i32, i32* %5, align 4, !dbg !234
%17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %16), !dbg !235
ret i32 0, !dbg !236
18: ; preds = %0
%19 = landingpad { i8*, i32 }
cleanup, !dbg !237
%20 = extractvalue { i8*, i32 } %19, 0, !dbg !237
store i8* %20, i8** %3, align 8, !dbg !237
%21 = extractvalue { i8*, i32 } %19, 1, !dbg !237
store i32 %21, i32* %4, align 4, !dbg !237
call void @_ZdlPv(i8* %6) #8, !dbg !221
br label %22, !dbg !221
22: ; preds = %18
%23 = load i8*, i8** %3, align 8, !dbg !221
%24 = load i32, i32* %4, align 4, !dbg !221
%25 = insertvalue { i8*, i32 } undef, i8* %23, 0, !dbg !221
%26 = insertvalue { i8*, i32 } %25, i32 %24, 1, !dbg !221
resume { i8*, i32 } %26, !dbg !221
}
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
declare dso_local nonnull i8* @_Znwm(i64) #2
define linkonce_odr dso_local void @_ZN6AnimalC2Ei(%class.Animal* nonnull dereferenceable(4) %0, i32 %1) unnamed_addr #3 comdat align 2 !dbg !238 {
%3 = alloca %class.Animal*, align 8
%4 = alloca i32, align 4
store %class.Animal* %0, %class.Animal** %3, align 8
call void @llvm.dbg.declare(metadata %class.Animal** %3, metadata !239, metadata !DIExpression()), !dbg !240
store i32 %1, i32* %4, align 4
call void @llvm.dbg.declare(metadata i32* %4, metadata !241, metadata !DIExpression()), !dbg !242
%5 = load %class.Animal*, %class.Animal** %3, align 8
%6 = load i32, i32* %4, align 4, !dbg !243
%7 = getelementptr inbounds %class.Animal, %class.Animal* %5, i32 0, i32 0, !dbg !245
store i32 %6, i32* %7, align 4, !dbg !246
ret void, !dbg !247
}
declare dso_local i32 @__gxx_personality_v0(...)
declare dso_local void @_ZdlPv(i8*) #4
define linkonce_odr dso_local i32 @_ZN6Animal9report_idEv(%class.Animal* nonnull dereferenceable(4) %0) #5 comdat align 2 !dbg !248 {
%2 = alloca %class.Animal*, align 8
store %class.Animal* %0, %class.Animal** %2, align 8
call void @llvm.dbg.declare(metadata %class.Animal** %2, metadata !249, metadata !DIExpression()), !dbg !250
%3 = load %class.Animal*, %class.Animal** %2, align 8
%4 = getelementptr inbounds %class.Animal, %class.Animal* %3, i32 0, i32 0, !dbg !251
%5 = load i32, i32* %4, align 4, !dbg !251
ret i32 %5, !dbg !252
}
declare dso_local i32 @printf(i8*, ...) #6
define linkonce_odr dso_local void @_ZN6Animal9change_idEi(%class.Animal* nonnull dereferenceable(4) %0, i32 %1) #5 comdat align 2 !dbg !253 {
%3 = alloca %class.Animal*, align 8
%4 = alloca i32, align 4
store %class.Animal* %0, %class.Animal** %3, align 8
call void @llvm.dbg.declare(metadata %class.Animal** %3, metadata !254, metadata !DIExpression()), !dbg !255
store i32 %1, i32* %4, align 4
call void @llvm.dbg.declare(metadata i32* %4, metadata !256, metadata !DIExpression()), !dbg !257
%5 = load %class.Animal*, %class.Animal** %3, align 8
%6 = load i32, i32* %4, align 4, !dbg !258
%7 = getelementptr inbounds %class.Animal, %class.Animal* %5, i32 0, i32 0, !dbg !259
store i32 %6, i32* %7, align 4, !dbg !260
ret void, !dbg !261
}
When the c++ code lowers to LLVM IR, the class information seems to be implicit. Is there a way to know the _ZN6Animal9report_idEv
and _ZN6Animal9change_idEi
functions belong to the same class Animal
? Would the debug info help? Or I should just figure it out based on the function name?