I am trying to create a global variable in a function pass. The code is
gVar= new GlobalVariable(
/*Type=*/Int32Type,
/*isConstant=*/false,
/*Linkage=*/GlobalValue::CommonLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/"gVar",
/*ThreadLocalMode*/GlobalVariable::InitialExecTLSModel);
However, I keep getting the following compiler error:
error: no matching function for call to ‘llvm::GlobalVariable::GlobalVariable(const llvm::Type*&, bool, llvm::GlobalValue::LinkageTypes, int, const char [4], llvm::GlobalVariable::ThreadLocalMode)’
Could you please tell me the right way to declare a global variable in llvm? Thank you very much!
In addition, I've referred to the header file:
http://llvm.org/docs/doxygen/html/GlobalVariable_8h_source.html
and this post
How can I declare a global variable in LLVM?
You need to pass a Module to the constructor. There are plenty of examples in the LLVM code base for creating global vars. For example, in examples/ExceptionDemo/ExceptionDemo.cpp:
new llvm::GlobalVariable(module,
stringConstant->getType(),
true,
llvm::GlobalValue::LinkerPrivateLinkage,
stringConstant,
"");
By the way - important note: you should not be creating new globals or doing anything else that modifies a module in a function pass. If you have to do that, you need a module pass.
Related
Good day. I am facing an issue with creating a GlobalVariable. I already have an extern for that global in a header file to use it in the following way
extern const void* DATA_TABLE[];
And with a LLVM PASS, I am trying to create this array with the same name and with an initializer. So, I have the following:
GlobalVariable *gvar_data = new GlobalVariable(
M, blockItems->getType(), true, GlobalValue::CommonLinkage,
blockItems, "DATA_TABLE");
gvar_data->setAlignment(16);
gvar_data->setSection("data_section");
gvar_data->addAttribute(llvm::Attribute::OptimizeNone);
I am not sure if I am using the correct Linkage or not.
The pass has failed to complete it. Here is the runtime fault. Any guess what I am doing incorrect?
'common' global must have a zero initializer!
[10 x i8*]* #DATA_TABLE.1
LLVM ERROR: Broken module found, compilation aborted:::::::::!
If you don't call setInitializer(), the GlobalVariable you make is extern. There is a function that'll supply an all-zeroes initializer for a type you supply, I don't remember its name off-hand, or you can make a suitable initializer yourself using classes such as ConstantStruct, ConstantInt and their siblings.
I wrote a function:
function getArtists(where='', artistactive = true){
//yadayada
return artists;
}
and included it, in a template, after the following
<cfstoredproc datasource="#request.dsn#" procedure="GetArtists">
<cfprocresult name="GetArtists">
</cfstoredproc>
This produces an error:
Routines cannot be declared more than once. The routine getArtists has
been declared twice in different templates
Ok, so question 1: ColdFusion thinks that a function and a stored procedure are both 'routines' and cannot be declared twice?
So, next thing I did was to include my functions template before the stored procedure... and it seems to be fine, with that.
Question 2: what gives?
You should believe the error. In testing your code I get no error when declaring the function and then calling a stored proc of the same name. when I dump out the variables scope using <cfdump var="#variables#"> I only see the result set (not the function) because the function has been overwritten by the result set. If I try to call the function after declaring the function and then overwriting it I get "Incorrect entity type for being a function" as my error.
Remember that the CF Compiler goes through your code and compiles UDFs and components first. They are not compiled at runtime. The error you are referencing occurs during the compile, not the runtime. For this reason I think it is more likely that your UDF routine is actually being included more than once. Take a look at the debug information at the bottom and search for that file and see if this is the case - or examine custom tag calls and other ways where files are doubled.
Advice: As a rule UDF should be declared in their own space (onRequest() is a good spot for it) and should be protected from this sort of thing. I use a variable like "lib" and store my functions (which are members of objects just like in Java) as lib.function1(), lib.function2(). The way you are doing it leads to unpredictability. That last is just my Opinion - trying to help. :)
Reading a code base and desperately trying to understand it.
template<typename selection>
void run_z_p_selection(xml_config &my_config){
system::start();
std::shared_ptr<selection> my = std::make_shared<selection>(my_config, machine, enable, timet);
system::addSelection(my);
}
(xml_config &my config){}. Is this an object being created as an address? I don't understand.
Where are all the (my_config, machine, enable, timet) coming from if they are not input arguments to the function?
That is something called pass by reference
It's hard to tell without seeing the whole code base, but it looks like those are global variables. Maybe system::start() sets them up?
xml_config &my_config is a reference: http://en.cppreference.com/w/cpp/language/reference A reference is an:
Alias to an already-existing object or function
my_config is the argument passed in that is an xml_config&. machine, enable, and timet are all variables which are in scope for your function. And that could mean a lot of things.
If run_z_p_selection is a method, these could be member variables.
Because run_z_p_selection is a template I assume that it is defined in your header, so you shouldn't need to look in included source files for these, only in included headers.
The variables must either be defined in run_z_p_selection's namespace, a containing namespace, or the global namespace.
If you have Visual Studio you can select the variable you want to know about and press: Ctrl + F12 to jump to where it is defined in your project.
I am unable to use lldb to invoke simple, non-templated functions that take string arguments. Is there any way to get lldb to understand the C++ datatype "string", which is a commonly used datatype in C++ programs?
The sample source code here just creates a simple class with a few constructors, and then calls them (includes of "iostream" and "string" omitted):
using namespace std;
struct lldbtest{
int bar=5;
lldbtest(){bar=6;}
lldbtest(int foo){bar=foo;}
lldbtest(string fum){bar=7;}
};
int main(){
string name="fum";
lldbtest x,y(3);
cout<<x.bar<<y.bar<<endl;
return 0;
}
When compiled on Mac Maverick with
g++ -g -std=c++11 -o testconstructor testconstructor.cpp
the program runs and prints the expected output of "63".
However, when a breakpoint is set in main just before the return statement, and attempt to invoke the constructor fails with a cryptic error message:
p lldbtest(string("hey there"))
error: call to a function 'lldbtest::lldbtest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)' ('_ZN8lldbtestC1ENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE') that is not present in the target
error: The expression could not be prepared to run in the target
Possibly relevant as well, the command:
p lldbtest(name)
prints nothing at all.
Also, calling the constructor with a string literal also failed, the standard way:
p lldbtest("foo")
gives a similar long error:
error: call to a function
'lldbtest::lldbtest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)' ('_ZN8lldbtestC1ENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE') that is not present in the targeterror: The expression could not be prepared to run in the target
Is there any way to get lldb to understand and use the C++ "string" datatype? I have a number of functions taking string arguments and need a way to invoke these functions from the debugger. On a Mac.
THE PROBLEM
This is due to a subtle problem with your code, that boils down to the following wording from the C++ Standard:
7.1.2p3-4 Function specifiers [dcl.fct.spec]
A function defined within a class definition is an inline function.
...
An inline function shall be defined in every translation unit in which it is odr-used, and shall have exactly the same definition in every case (3.2).
Your constructor, lldbtest(std::string) is defined within the body of lldbtest which means that it will implicitly be inline, which further means that the compiler will not generate any code for it, unless it is used in the translation unit.
Since the definition must be present in every translation unit that potentially calls it we can imagine the compiler saying; "heck, I don't need to do this.. if someone else uses it, they will generate the code".
lldb will look for a function definition which doesn't exist, since gcc didn't generate one; because you didn't use it.
THE SOLUTION
If we change the definition of lldbtest to the following I bet it will work as you intended:
struct lldbtest{
int bar=5;
lldbtest();
lldbtest(int foo);
lldbtest(string fum);
};
lldbtest::lldbtest() { bar=6; }
lldbtest::lldbtest(int) { bar=7; }
lldbtest::lldbtest(string) { bar=8; }
But.. what about p lldbtest(name)?
The command p in lldb is used to print* information, but it can also be used to evaluate expressions.
lldbtest(name) will not call the constructor of lldbtest with a variable called name, it's equivalent of declaring a variable called name of type lldbtest; ie. lldbtest name is sementically equivalent.
Going to answer the asked question here instead of addressing the problem with the op's code. Especially since this took me a while to figure out.
Use a string in a function invocation in lldb in C++
(This post helped greatly, and is a good read: Dancing in The Debugger)
If I have the following code in a function, I will not get an error and I can compile no problem, however, once I put it in global scope I will get an error for "cannot allocate an array of size zero", along with several other errors. Why does this happen and how can I get rid of the errors. I am aware of the risk of global variables, this is just a simple test case.
int* intest[2];
intest[0] = new int;
You are allowed declarations in global scope but not allowed to use the new operator or the assignment. Thus you need the declaration int *intest[2] in global scope (and all your code would see it) but C++ requires the new to be in the sequence of your main code. (probably in some sort of start up function for the app).
EDIT: as pointed out by #phresnel you can use the new operator in this scope but not the assignment (this is unusual but not illegal). However the following new operators used as initiation will work for you:
int *x[2]={new int,new int};
In general the use of such a global buffer is highly discouraged and is considered an anti-pattern - if you can avoid using it you probably should.
int* intest[2];
Is valid placing in the local scope however :
intest[0] = new int;
is not.
The difference is that the upper one is a initalisation statement (creating the variable) and the lower one is a executed code segment.
Code that should be "executed" cant be called in the global scope, for example you cant call a function in the global scope. When would that function be called?
I can create how many variables i want in the global scope but i cant run code from it except from constructors being called when initialisating the global variables.
If you want to execute code such as :
intest[0] = new int;
You would have to execute it trough main or another function, otherwise the program would not know when to execute it.
AFAIK, the global scope only allow u put define and declaration on it. Whereas intest[0] = new int; is a assignment that c/c++ compiler shall fail while compile.