How to create a ConstantInt in LLVM? - llvm

I'm not sure how to create a ConstantInt in LLVM- I know the number I would like to create, but I'm unsure how I can make a ConstantInt representing that number; I can't seem to find the constructor I need in the documentation.
I'm thinking it has to be along the lines of
ConstantInt consVal = new ConstantInt(something here).
I know I want it to be an int type, and I know my value... I just want to create a number!

Most things in LLVM are created through a static method call instead of directly using a constructor. One reason is that an existing object can be returned instead of creating a new instance.
The static members of ConstantInt have a number of creation methods. You're probably most interested in get (Type *Ty, uint64_t V, bool isSigned=false) and, if you don't already have an integer type, IntegerType::get (LLVMContext &C, unsigned NumBits).

To make an a 32 bit integer:
llvm::ConstantInt::get(context, llvm::APInt(/*nbits*/32, value, /*bool*/is_signed));

To create a 32-bit integer constant:
llvm::Type *i32_type = llvm::IntegerType::getInt32Ty(llvm_context);
llvm::Constant *i32_val = llvm::ConstantInt::get(i32_type, -1/*value*/, true);

ConstantInt* const_int32 = ConstantInt::get( Context , APInt(32, StringRef("10"), 10));
where,
APInt(32, StringRef("10"), 10);
gets int value from string "10" with base 10.

Related

How to convert integer to char pointer in a function call

I am currently writing code that will read an xml file using the pugixml module. In my xml file I have several shape nodes that are differentiated by a shape_id attribute that gets a number.
For a specific need I have the shape_id number stored in an integer although in xml file the value of the respective attribute is of course a string (or char, have to check).
In order to retrieve the specific shape node, e.g. that with the attribute shape_id = 2 (just to give an example) I have written the function below.
pugixml provides a function find_child_by_attribute() with this call definition:
PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const
As you can see it requests the attribute value as a char pointer.
I manage to make it work with the two lines as in the code:
char char_shape_id = static_cast<char>(shape_id);
char* shape_id_ptr = &char_shape_id;
First I cast the integer shape_id into a char and then I take the address of this char and store it into a char pointer. I think it is an awkward way to do but I cannot figure out how to do this in a more elegant way.
I've tried following but failed.
char* shape_id_ptr = &(static_cast<char>(shape_id));
This seems to be invalid code.
What seems also to work is when I have following function call in the return line:
return root_node.child(sNodeNames.case_def_name.c_str()).find_child_by_attribute(sNodeNames.shape_name.c_str(),"item_id", (char*)shape_id);
I also tried to have a unique_ptr or shared_ptr instead of the raw char pointer but somehow I cannot figure out how to make this pointer cooperate with the find_child_by_attribute(). My shared pointer definition is currently
char char_shape_id = static_cast<char>(shape_id);
std::shared_ptr<char> shape_id_ptr(&char_shape_id);
but as I said, this is not accepted by the function.
//returns the node shape with a given shape_id number
pugi::xml_node nXml::tXmlShape::GetShapeNode(const int shape_id, const pugi::xml_node& root_node)
{
char char_shape_id = static_cast<char>(shape_id);
char* shape_id_ptr = &char_shape_id;
nXml::sXmlNodeNames sNodeNames;
nXml::sXmlShapeTypes sShapeTypes;
return root_node.child(sNodeNames.case_def_name.c_str()).find_child_by_attribute(sNodeNames.shape_name.c_str(),"item_id", shape_id_ptr);
}
;
Apart from the pretty ugly return line phrasing is there a more elegant way to accomplish the transmission of a char pointer of an originally integer value to the function and how could I realize this with a unique_ptr respectively shared_ptr?

Array type 'char [n]' and 'uint8 [n]' is not assignable

I'm trying to convert two types of values: char and uint8.
I have a function someFunction(TLabel *label, TEdit *edit). Inside of this function, I have a variable char var[6+1].
What I'm trying to do:
Get an Alphanumeric text (input of TEdit *edit), convert this text and put it inside of the var.
I know that if I call this function and put the *label and the *edit I can get whatever I want, but the problem is the conversion to associate the text of *edit in the var.
An example of my code (inside of the function):
char var[6+1];
label->Text = "Some text";
var = edit->Text;
//I will put var value inside of an another char (like a #define) that is in a struct, but doesn't matter for now
my_struct.valueOfVar = var;
And I have another function, it's the same code but the valueOfVar above is a uint8, and I can't convert it, too:
uint8 valueOfAnotherVar[6+1];
The issue is not with the types of the elements in the arrays, but rather that you simply can't assign one static array to another like this:
char a[7];
uint8 b[7];
a = b; // error
Instead, if you want to copy the values in the arrays, you can use std::copy like this:
std::copy(std::begin(b), std::end(b), std::begin(a));
If you have a dynamic array, you can still use std::copy, but you have to use the size of the array:
std::copy(b, b + N, a);
Make sure that both a and b point to at least N elements, otherwise you'll invoke undefined behavior.
The Text of a TLabel or TEdit is a System::String, which is an alias for System::AnsiString in C++Builder 2007 and earlier, and for System::UnicodeString in C++Builder 2009 and later. You did not say which version you are using, but it makes a big difference in your example.
You can't assign anything directly to a fixed array, like char[7] or uint8[7], by using operator= like you are attempting to do. You will need to instead convert and copy the String data into the allocated memory of the arrays, eg:
char var[6+1] = {};
label->Text = "Some text"; // OK - String has a constructor for 'const char*'
// if using CB2007 or earlier:
strncpy(var, edit->Text.c_str(), 6);
// if using CB2009 or later:
strncpy(var, AnsiString(edit->Text).c_str(), 6);
And then you can use one of these to copy the contents of var into valueOfVar:
memcpy(my_struct.valueOfVar, var, 7);
std::copy(var, var+7, my_struct.valueOfVar);
std::copy_n(var, 7, my_struct.valueOfVar);

Converting a temporary character array to a string in D

I'm learning D language (I know C++ well)... I want to do some Windows specific stuff so I wrote this just to try out the API:
import core.sys.windows.windows;
import std.stdio;
string name()
{
char buffer[100];
uint size = 100;
GetComputerNameA(&buffer[0], &size);
return buffer;
}
void main()
{
writeln(name());
}
I get in my return statement:
test.d(11): Error: cannot implicitly convert expression (buffer) of type char[100] to string
Ok, in C++ it would call the constructor to make a string. It says implicit so lets cast it with a C style cast: return (string)buffer;.
test.d(11): Error: C style cast illegal, use cast(string)buffer
Ah ok, I remember, different syntax.
return cast(string)buffer;
Now it compiles but I just get garbage.
I assume that is is because it's storing a pointer in the string to the temporary buffer. I don't want to do this, I want to copy the characters into a string but annoyingly I can't seem to find how to do this?
So questions:
How do I construct an actual string from a char array that allocates storage properly? (Copies the characters)
Allocating a buffer of a random size like this and converting to a string seems ugly. Is there a proper way to do this in D? (I'm talking about the general question, not specifically this API just in case there is another API to get the computer name).
If either of those are answered in a manual where should I have looked to find details?
Thanks for any help and advice.
I think you need:
string name()
{
char buffer[100];
uint size = 100;
GetComputerNameA(buffer.ptr, &size);
return buffer[0 .. size].idup;
}
buffer.idup is the standard way to get an immutable copy. For this case, since you want a dynamically-sized string (and recall that string is really just shorthand for immutable(char)[]), you want buffer[0..size].idup, using D's array slicing.
See http://dlang.org/arrays.html for more information.
(This is a bit of a nitpick, but you may want to use buffer.ptr instead of &buffer[0], mostly for readability's sake.)

wchar_t* to short int conversion

One of the function in a 3rd party class return awchar_t* that holding a resource id (I don't know why it uses wchar_t* type ) I need to convert this pointer to short int
This method, using AND operator works for me. but it seems like not the correct way. is there any proper way to do this?
wchar_t* s;
short int b = (unsigned long)(s) & 0xFFFF;
wchar_t* s; // I assume this is what you meant
short int b = static_cast<short int>(reinterpret_cast<intptr_t>(s))
You could also replace short int b with auto b, and it will be deduced as short int from the type of the right-hand expression.
It returns the resource ID as a wchar_t* because that is the data type that Windows uses to carry resource identifiers. Resources can be identified by either numeric ID or by name. If numeric, the pointer itself contains the actual ID number encoded in its lower 16 bits. Otherwise it is a normal pointer to a null-terminated string elsewhere in memory. There is an IS_INTRESOURCE() macro to differentiate which is the actual case, eg:
wchar_t *s = ...;
if (IS_INTRESOURCE(s))
{
// s is a numeric ID...
WORD b = (WORD) s;
...
}
else
{
// s is a null-terminated name string
...
}
Did you mean in your code wchar_t *s;?
I'd do the conversion more explicit using
short int b = reinterpret_cast<short int>(s);
If it fits your application needs, I suggest using a data type with a fixed nr of bits, e.g. uint16_t. Using short int means you only know for sure your variable has at least 16 bits. An additional question: Why do you not use unsigned short int, instead of (signed) short int?
In general, knowing the exact nr of bits make things a little more predictable, and makes it easier to know exactly what happens when you cast or use bitmasks.

passing char* back and forth between functions

I have two functions and I'm trying to pass a buffer from one function to the other and have it modify the contents, but I cannot seem to get it to work..here is what i have:
void caller ()
{
char * datum;
populate (&datum);
}
void populate (void * buf)
{
unsigned char * datump;
int dtsz;
getData (datump,dtsz); // This function puts "001" in datump and dtsz = 4
buf = new unsigned char[dtsz];
memset(datumbuf,0,sizeof(buf));
memcpy (buf,datump,dtsz);
}
When I debug through everything seems to be exactly like it should be until I get to memcpy. It does not seem like memcpy actually does anything.
The reason "datumbuf = new unsigned char[dtsz]" is done is because the "getData()" function returns each time with a different size depending on the data size, hence the size can't be statically assigned.
When I get back to the main "caller()" function, the "datum" contains junk.
Any ideas why this is happening and how it can be fixed?
Thanks
It's not C++, it's C. Use std::string and forget about such buffers if you're using C++.
You don't modify buf in populate. You don't allocate memory for datump (don't know what getData does).
Your populate function should just return a pointer. that way everything is much easier.
char * populate()
{
...
buf = new unsigned char[dtsz];
...
return buf;
}
...and then you call it like this:
char * datum = populate()
your current code doesn't work because you're confused between value and reference parameters. You pass datum 'by reference' populate(&datum) but `populate treats it like a value parameter.
That memset line is strange and wrong, sizeof(datumbuf) is the pointer size (4 or 8), not the arrays length.
If its 8, it will be writing over other stuff, since the array you describe is only 4 long. Still, I doubt thats your actual error.