How to create named local variable in llvm? - c++

In a struct like this:
struct point{
int x0;
int y0;
};
How can I pass the names x0 and y0 to llvm when I create the llvm::StructType with C++ API?

You can't; in LLVM IR, fields of structs do not have names.
What you can do depends on what you are trying to achieve:
If you want to enable debug info for these fields, this is not the correct approach anyway - instead, use a DIBuilder to define the struct type.
If you want to make the IR's textual representation (.ll files and dump() results) more readable, you can do something different - whenever a field is accessed, have the frontend use the field name for that field's value. For example:
%p.py0 = getelementptr %point* %p, i32 0, i32 1
%p.y0 = load i32* %p.py0
the getelementptr that accesses the 2nd field has a name that indicates it's a pointer to a field called y0, and the load has a name that indicates it's the actual field. Also notice how the name includes the name of the variable those were accessed from, for extra readability.

Related

Enumerating properties in a type in C++

I'm working on a Wordclock with an Arduino so we're in C++. I want to save the corresponding Pixels and length of the words in a type so I can call a function that takes the Word to display as a property.
So here is what I came up with:
(Pseudocode)
type WORD
property1 = pixelPosition (integer)
property2 = wordLength (also integer)
I also would like to implement all the values in a compact form like in a enum like this:
word1= (123, 3);
Instead of this:
word1.pixelPos = 123;
word1.length = 3;
Unfortunately I didnt find a way to set two values in an enum. Is there a way I can create a custom type and set it to be the kind of type I want to enum?

How to access attributes from subtypes

I followed the TSL documentation on attributes and created two classes:
[GraphNode]
cell struct Fruit
{
string color;
}
[GraphNode, BaseType : Fruit]
cell struct Apple
{
string variety;
}
I used the generated code like this:
Apple apple = new Apple();
Console.WriteLine(apple.variety);
Console.WriteLine(apple.color);
The code can access the variety field, but cannot access the color field:
'Apple' does not contain a definition for 'color' and no extension method 'color' accepting a first argument of type 'Apple' could be found (are you missing a using directive or an assembly reference?)
How can I access the inherited attribute?
Those attributes do not have an intrinsic meaning apart from the meaning you attach to them. "BaseType" does not make Apple derive from Fruit. You can just ask in your code for the value of the attribute "BaseType" on your cell.

LLVM: How to traverse Module metadata to find a value?

I have this metadata tree in my LLVM module:
!meta.test = !{!0}
!0 = !{"str1", "str2", !1}
!1 = !{!2, !3, null}
!2 = !{"str3", i8 5}
I want to be able to get the value: i8 5.
I am trying it using M->getNamedMetadata("meta.test"), but I'm unable to traverse the metadata tree using the LLVM API to reach that value.
How should I do this?
Cheers.
For LLVM 3.6 onwards
getNamedMetadata returns NamedMetadata, you can use getOperand(unsigned) to get MDNode and can cast to your appropriate type as per your use.
so M->getNamedMetadata("meta.test")->getOperand(0) will get you metadataNode !0 MDNode.
you can use cast< ValueAsMetadata >(MDNode)->getvalue() to get Value i8 5
or you can use cast< MDString >(MDNode)->getString() to get Value str1.
so in short you can traverse metadata MDNodes using getOperand() call and cast it to your use as per hierarchy. see this for more info.

How to access data stored in structure within array

I have an array which holds a structures which represents form fields of a web page. My question is how can I easily access data in the array to get the value I am looking for. In this case I am trying to get the value for the field with the name "availableScreensCSV" for now I am looping thru the array and if the key = "name' and is "availableScreensCSV" then I get the data for the value. I hope there is a simpler way to do this. Below is what my array / structure looks like
array
1 struct
NAME templateId
TYPE hidden
VALUE [empty string]
2 struct
NAME useTestSystem
TYPE hidden
VALUE false
3 struct
NAME availableScreensCSV
TYPE hidden
VALUE ICASR,ICADM,ICTQ1,ICTQA,ICTQB,ICTQ6,ICFGB
4 struct
NAME ccna
TYPE hidden
VALUE IFX
5 struct
NAME pon
TYPE hidden
VALUE I11192014013
6 struct
NAME asr
TYPE hidden
VALUE 1432310020
7 struct
NAME icsc
TYPE hidden
VALUE SW80
My gut reaction is, "how did your data get into that array?" If it's a form post, you should be able to simply get form fields by name: form.availableScreensCSV -- but that hinges on your form post.
Since you neglected to mention, I'm assuming that the array may not always be in the same order, in which case looping is your only reasonable option. There are functional approaches like arrayFind with an inline function but that is some syntactic sugar on top of a loop. If you're just looking for cleaner, more readable code, then arrayFind with an inline function may be the way to go.
If you're looking for the most performant option, then a simple loop that does a <cfbreak /> once it finds the desired element will be the best option.

How do I insert this custom data type with libpq?

I'm having some difficulty with inserting some data using libpq. I have two custom data types:
create type size as (width real, height real);
create type rotated_rect as (angle real, center point, bounding_box box, size size)
and I would like to insert a record into a table which has a rotated_rect field, so for the field using libpq I'm putting together the string value:
paramv[3] = "(10.5,10.1,10.2,20,20,20,40,(5,5))";
However, it's giving me the error: invalid input syntax for type point: "10.1"
I've also tried:
paramv[3] = "(10.5,(10.1,10.2),20,20,20,40,(5,5))"; -> invalid input syntax for "(10.1"
paramv[3] = "(10.5,(10.1,10.2),(20,20,20,40),(5,5))"; -> as above
and the sql command I'm using is:
res = PQexecParams(conn, "insert into test (r,b,s,rr) values ($1::real,$2::box,$3::size,$4::rotated_rect)", 4, NULL, paramv, NULL, NULL,0);
How do I fix this?
This works (tested in Postgres 9.3):
SELECT '(10.5,"(10.1,10.2)","(20,20,20,40)","(5,5)")'::rotated_rect
Returns:
'(10.5,"(10.1,10.2)","(20,40),(20,20)","(5,5)")'
Note the different syntax for box. Try this form.
What got me were that escaped double quotes and parenthesis need to be used around the values representing a field of the custom compound data type which requires more than one value to create, so:
paramv[0] = "(10.5,\"(10.1,10.2)\",\"(20,20,20,40)\",\"(5,5)\")";
As this string is used as a parameter, the single quotes that would usually wrap the outer parenthesis are not needed.
In a non-parameterised query, it would be implemented like so with the single quotes:
res = PQexec(conn, "insert into test (rr) values ('(10.5,\"(10.1,10.2)\",\"(20,20,20,40)\",\"(5,5)\")')");