For a small help

Hi,

I want to ask for a small help for creating an instruction that calls
e member method of an object. I suppose that this is not a headache
but I am impatient in learning :slight_smile: I would be very thankful if you can
show me an example snippet code that does this in LLVM. Below is
described my case.

Let's say I have a class TestClass

class TestClass
{
    int testMethod(int a);
}

and I want to create a call instruction that calls
obj.testMethod(input) where obj is an instance of TestClass

TestClass obj; // I have this declared prior
int input = 1; // I have declared prior
int output; // I have this declared prior too
output = obj.testObject(input); // I want to create this instruction

Thanks,
Ferad

Ferad Zyulkyarov wrote:

Hi,

I want to ask for a small help for creating an instruction that calls
e member method of an object. I suppose that this is not a headache
but I am impatient in learning :slight_smile: I would be very thankful if you can
show me an example snippet code that does this in LLVM. Below is
described my case.

Let's say I have a class TestClass

class TestClass
{
    int testMethod(int a);
}

and I want to create a call instruction that calls
obj.testMethod(input) where obj is an instance of TestClass

TestClass obj; // I have this declared prior
int input = 1; // I have declared prior
int output; // I have this declared prior too
output = obj.testObject(input); // I want to create this instruction

Thanks,
Ferad
  
You can use the LLVM demo page ( http://llvm.org/demo/index.cgi ) to find out what LLVM code is generated for some C++ code. For example, the above produces:

; ModuleID = '/tmp/webcompile/_6207_0.bc'
target datalayout = "e-p:32:32"
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
  %struct.TestClass = type { ubyte }

implementation ; Functions:

void %_Z4funcv() {
entry:
  %obj = alloca %struct.TestClass, align 1 ; <%struct.TestClass*> [#uses=1]
  %tmp1 = call int %_ZN9TestClass10testMethodEi( %struct.TestClass* %obj, int 1 ) ; <int> [#uses=0]
  ret void
}

declare int %_ZN9TestClass10testMethodEi(%struct.TestClass*, int)

The object on which you call the method becomes the first argument to the method.

Hi Ferad,

Hi,

I want to ask for a small help for creating an instruction that calls
e member method of an object. I suppose that this is not a headache
but I am impatient in learning :slight_smile: I would be very thankful if you can
show me an example snippet code that does this in LLVM. Below is
described my case.

Let's say I have a class TestClass

class TestClass
{
    int testMethod(int a);
}

and I want to create a call instruction that calls
obj.testMethod(input) where obj is an instance of TestClass

TestClass obj; // I have this declared prior
int input = 1; // I have declared prior
int output; // I have this declared prior too
output = obj.testObject(input); // I want to create this instruction

Why not just code this up into a C++ function and submit it to the
online demo to see what is produced? I submitted this:

class TestClass {
public:
  int testMethod(int a);
  virtual int testMethod2(int a);
};

int doit() {
  TestClass obj; // I have this declared prior
  int input = 1; // I have declared prior
  int output; // I have this declared prior too
  output = obj.testMethod(input); // I want to create this inst
  output += obj.testMethod2(input); // Try virtual too
  return output;
}

to http://llvm.org/demo/ and got:

target datalayout = "e-p:32:32"
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
  %struct.TestClass = type { int (...)** }
%vtable for TestClass = external constant [3 x int (...)*] ; <[3 x int (...)*]*> [#uses=1]

implementation ; Functions:

int %doit()() {
entry:
  %obj = alloca %struct.TestClass, align 16 ; <%struct.TestClass*> [#uses=3]
  %tmp = getelementptr %struct.TestClass* %obj, int 0, uint 0 ; <int (...)***> [#uses=1]
  store int (...)** getelementptr ([3 x int (...)*]* %vtable for TestClass, int 0, long 2), int (...)*** %tmp
  %tmp1 = call int %TestClass::testMethod(int)( %struct.TestClass* %obj, int 1 ) ; <int> [#uses=1]
  %tmp3 = call int %TestClass::testMethod2(int)( %struct.TestClass* %obj, int 1 ) ; <int> [#uses=1]
  %tmp5 = add int %tmp3, %tmp1 ; <int> [#uses=1]
  ret int %tmp5
}

declare int %TestClass::testMethod(int)(%struct.TestClass*, int)

declare int %TestClass::testMethod2(int)(%struct.TestClass*, int)

Note the "%vtable for TestClass" external constant array.

Hope this helps,

Reid.

Reid, Jeff thanks for the quick response. This will help. I didn't
think of this way when sending the mail.. just blocked :slight_smile:

Thanks again,
Ferad

The name mangling is not very pretty though and it is specific to the C++ front-end. What is the best manner to deal with that problem?

Luc Bourhis

Luc Bourhis wrote:


  
[…]
	%obj = alloca %struct.TestClass, align 1		; <%struct.TestClass*>  
[#uses=1]
	%tmp1 = call int %_ZN9TestClass10testMethodEi( %struct.TestClass* % 
obj, int 1 )		; <int> [#uses=0]
	ret void
}

declare int %_ZN9TestClass10testMethodEi(%struct.TestClass*, int)
    

The name mangling is not very pretty though and it is specific to the  
C++ front-end. What is the best manner to deal with that problem?

Luc Bourhis

What exactly is the problem that needs dealing with?

If you intend to link with C++ code, there is no choice but to live with it. If you are doing your own language, you can do whatever you want for names.

[…]
  %obj = alloca %struct.TestClass, align 1 ; <%struct.TestClass*>
[#uses=1]
  %tmp1 = call int %_ZN9TestClass10testMethodEi( %struct.TestClass* %
obj, int 1 ) ; [#uses=0]
  ret void
}

declare int %_ZN9TestClass10testMethodEi(%struct.TestClass*, int)

The name mangling is not very pretty though and it is specific to the
C++ front-end. What is the best manner to deal with that problem?

Luc Bourhis

What exactly is the problem that needs dealing with?

If you intend to link with C++ code, there is no choice but to live with it.

So I did. Fair enough.

Luc