Tehreem
Tehreem

Reputation: 999

How to create a string in LLVM IR

I am writing a pass to do some modifications to IR and need to create a function call which requires a string as parameter. I created string using:

string str = fn.getName();  // Name of a function is what I need to pass as argument
Value * v = builder.CreateGlobalString(StringRef(str), "func_name");

But this creates a string with type:

[4 x i8]*

When I print the required argument type for the function, I get:

%"class.std::__cxx11::basic_string"*

How can I create a string with %"class.std::__cxx11::basic_string"* type?

Upvotes: 3

Views: 808

Answers (1)

Dmytro Biriukov
Dmytro Biriukov

Reputation: 11

Indeed, when you use 'CreateGlobalString' from 'IRBuilder', you are creating 'GlobalVariable' with [N x i8]* initializer (an array of N elements of type i8 - a char type).

The std::string is something more complex for LLVM IR. For instance, the following line of code in your program

std::string std;

will be represented in IR by many lines, among them are lines to define types

%"class.std::__cxx11::basic_string" = type { %"struct.std::__cxx11::basic_string<char>::_Alloc_hider", i64, %union.anon }
%"struct.std::__cxx11::basic_string<char>::_Alloc_hider" = type { i8* }
%union.anon = type { i64, [8 x i8] }

directly in the function, when you have std::string on stack, you will find at least following lines to allocate object

  %2 = alloca %"class.std::__cxx11::basic_string", align 8

to call default ctor

call void @_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev(%"class.std::__cxx11::basic_string"* noundef nonnull align 8 dereferenceable(32) %2) #2

and finally to call dtor

call void @_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev(%"class.std::__cxx11::basic_string"* noundef nonnull align 8 dereferenceable(32) %2) #2

and also you will find declarations of these functions (ctor and dtor)

declare void @_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev(%"class.std::__cxx11::basic_string"* noundef nonnull align 8 dereferenceable(32)) unnamed_addr #1
declare void @_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev(%"class.std::__cxx11::basic_string"* noundef nonnull align 8 dereferenceable(32)) unnamed_addr #1

So likely the easiest solution here is to make a wrapper function as mentioned above.

Upvotes: 1

Related Questions