Search code examples
c++callllvm

How to locate the function name in the llvm bytecode, using call and alias instruction?


I have the following C++ code:

class Date {
public:  
  Date(int, int, int);
private:
  int year; int month; int day;
};

extern "C" int main(int argc, char *argv[])
{
   Date today(1,9,2014);
   //....
   return 0;
}

Date::Date(int d, int m, int y) { day = d; month = m; year =y; }

The corresponding bytecode is:

@_ZN4DateC1Eiii = alias void (%class.Date*, i32, i32, i32)* @_ZN4DateC2Eiii

define i32 @main(i32 %argc, i8** %argv) {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 4
  %today = alloca %class.Date, align 4
  store i32 0, i32* %retval
  store i32 %argc, i32* %argc.addr, align 4
  call void @llvm.dbg.declare(metadata !{i32* %argc.addr}, metadata !922), !dbg !923
  store i8** %argv, i8*** %argv.addr, align 4
  call void @llvm.dbg.declare(metadata !{i8*** %argv.addr}, metadata !924), !dbg !923
  call void @llvm.dbg.declare(metadata !{%class.Date* %today}, metadata !925), !dbg !927
  call void @_ZN4DateC1Eiii(%class.Date* %today, i32 1, i32 9, i32 1999), !dbg !927
  //...
  ret i32 0, !dbg !930
}
  //...
define void @_ZN4DateC2Eiii(%class.Date* %this, i32 %d, i32 %m, i32 %y) unnamed_addr nounwind align 2 {
entry:
  //...
}

I'm doing a parse of this code and I need to know how to get to @ _ZN4DateC2Eiii function, starting from the call ??

call void @ _ZN4DateC1Eiii (class.Date% *% today, i32 1, i32 9, i32 1999)! dbg! 927.

Solution

  • The line

    call void @_ZN4DateC1Eiii(class.Date%* %today, i32 1, i32 9, i32 1999), !dbg !927
    

    is an instruction of type CallInst. If it was a direct function call, you could have used CallInst::getCalledFunction() to get the called function, and you can get a function's name via getName().

    With indirect function calls, you need to invoke the instruction's GetCalledValue() method, which returns some value. You then have to manually check what that value is and handle it appropriately.

    In your case, with an indirect call to an alias, it should be something like

    (cast<GlobalAlias>(MyCallInst->getCalledValue()))->getAliasee()->getName();
    //                     ^              ^                 ^
    // Declared type:   CallInst        Value           Constant
    // Actual type:     CallInst     GlobalAlias        Function
    

    (added annotations of what types are involved below, to help with understanding this complex line)

    Noticed I have used cast, which assumes you know that the called value is in fact an alias. If you're not certain of that, use isa or dyn_cast instead.