I have a GlobalValue I would like to find the DILocation for. I can see the metadata exists, but can't find an obvious lookup path to get at it. Doing the same for llvm::Instruction is easy, but this isn't obvious.
The easiest thing to do is to create a DIGlobalVariable (or grab the DIGlobalVariable) and ask it what its file, line, column etc are. You'll find the global by iterating through the global variables in the compile unit.
The difference is this: an instruction has a location because we're going to build up a line table from it and it can be moved around so we'll end up accessing it, copying it, etc as we do code generation. A global variable doesn't need to point to its debug information because the only time we use the information is when we're creating debug information and the metadata points to the variable itself.
Related
Assume I have Variable called "Volume", for example. I now have a file with Settings in it. Every Settings looks like this: ":
I now go through this file from top to bottom, and I want the program to store the Setting in a Variable with an equal Name.
e.G. if there is "Volume: 76", I want the program to write "76" into the Variable "Volume". How can I make the program to get the right Variable just by the string? Is this even possible?
There is no code yet, since I haven't started working on it yet. I was making thoughts about it.
You can't use variables directly, since the name must be existent at compile time, but reading a file is runtime.
You can use std::map though. Each settings will be a key, and the value will be read in.
std::map<std::string, std::string> settings;
settings["volume"] = "76";
But, the values ("76" in this case) will be strings as well. You can not use differing types directly.
I think, its possible with type erasure, but thats really advanced (and iam not fluent with it!).
I working on a huge code base written many years ago. We're trying to implement multi-threading and I'm incharge of cleaning up global variables (sigh!)
My strategy is to move all global variables to a class, and then individual threads will use instances of that class and the globals will be accessed through class instance and -> operator.
In first go, I've compiled a list of global variables using nm by finding B and D group object names. The list is not complete, and incase of static variables, I don't get file and line number info.
The second stage is even more messy, I've to replace all globals in the code base with classinstance->global_name pattern. I'm using cscope Change text string for this. The problem is that in case of some globals, their name is also being used locally inside functions, and thus cscope is replacing them as well.
Any other way to go about it? Any strategies, or help please!
just some suggestions, from my experience:
use eclipse: the C++ indexer is very good, and when dealing with a large project I find it very useful to track variables. shift+ctrl+g (I have forgotten how to access to it from menus!) let you search all the references, ctrl+alt+h (open call hierarchy) the caller-callee trees...
use eclipse: it has good refactoring tools, that is able to rename a variable without touching same-name-different-scope variables. (it often fails in case there are templates involved. I find it good, better than visual studio 2008 counterpart).
use eclipse: I know, it get some time to get started with it, but after you get it, it's very powerful. It can deal easily with the existing makefile based project (file -> new -> project -> makefile project with existing code).
I would consider not to use class members, but accessors: it's possibile that some of them will be shared among threads, and need some locking in order to be properly used. So I would prefer: classinstance->get_global_name()
As a final note, I don't know whether using the eclipse indexer at command-line would be helpful for your task. You can find some examples googling for it.
This question/answer can give you some more hints: any C/C++ refactoring tool based on libclang? (even simplest "toy example" ). In particular I do quote "...C++ is a bitch of a language to transform"
Halfway there: if a function uses a local name that hides the global name, the object file won't have an undefined symbol. nm can show you those undefined symbols, and then you know in which files you must replace at least some instances of that name.
However, you still have a problem in the rare cases that a file uses both the global name and in another function hides the global name. I'm not sure if this can be resolved with --ffunction-sections; but I think so: nm can show the section and thus you'll see the undefined symbols used in foo() appear in section .text.foo.
I am writing a plugin for Stata in C++, and it seems to me that accessing the data depends on the order of variables passed to the plugin, as SF_vdata() only takes integer arguments to index the variables.
The best solution I have at the moment, is to first run ds, store the macro containing all variable names, and then call my plugin. My plugin can then search the macro for the variable that it is interested in, and get the index base don its position in the list.
This works, but I would like my plugin not to depend on certain Stata commands being run first. I know this is silly, as the plugin requires the dataset to be formatted in a specific way, but something feels wrong about first having to call ds and store a macro before calling my plugin.
Is there anyway to access the order of variable names from inside the plugin if ds is not called first?
I agree with Nick. Unfortunately your macro solution is the only answer, and is what I use. You can only access the data directly using the SF_data functions, as a "matrix", and that's all you get by default, there are no headers like in a table. I use macros to save all the data information and pass the whole dataset, reading the variable I'm interested in, just like you, and even wrote translators to retain the format settings, but have not yet used the value labels.
I'd like to get a value from a variable that's located deeply in the source code of the OpenCV library. Specifically, I'm trying to print out the value of stage_sum from the file haar.cpp. My starting point, facedetect.cpp, calls the method detectMultiScale, which then calls the function cvHaarDetectObjects, which calls cvHaarDetectObjectsForROC etc., until it finally reaches the function cvRunHaarClassifierCascadeSum, where stage_sum is calculated.
Is there a way I could get the value out to facedetect.cpp easily, without changing the declarations of all the preceding functions/methods, headers etc.? Simply trying to cout or printf the value directly in the source code hasn't given any results.
Thanks everyone for your help!
One option is simply to use a debugger.
However, if you want to do this programatically (i.e. access the variable as part of your application code), then unless the variable is exposed in the library's public interface, there are two options available:
Modify the library's source code, and recompile it.
Resort to undefined-behaviour (fiddling around with the raw bytes that make up an object, etc.).
Just to point the obvious, adding a std::cout() or printf() call inside haar.cpp won't do the trick. You need to recompile OpenCV for this changes to take effect and then reinstall the libraries on your system.
In C++ is there any function that returns "true" when the variable is defined or false in vice versa. Something like this:
bool isDefined(string varName)
{
if (a variable called "varName" is defined)
return true;
else
return false;
}
C++ is not a dynamic language. Which means, that the answer is no. You know this at compile time, not runtime.
There is no such a thing in runtime as it doesn't make sense in a non-dynamic language as C++.
However you can use it inside a sizeof to test if it exists on compile time without side-effects.
(void)sizeof(variable);
That will stop compilation if var doesn't exist.
As already stated, the C++ runtime system does not support the querying of whether or not a variable is declared or not. In general a C++ binary doesn't contain information on variable symbols or their mappings to their location. Technically, this information would be available in a binary compiled with debugging information, and you could certainly query the debugging information to see if a variable name is present at a given location in code, but it would be a dirty hack at best (If you're curious to see what it might look at, I posted a terrible snippet # Call a function named in a string variable in C which calls a C function by a string using the DWARF debugging information. Doing something like this is not advised)
Microsoft has two extensions to C++ named: __if_exists and __if_not_exists. They can be useful in some cases, but they don't take string arguments.
If you really need such a functionality you can add all your variables to a set and then query that set for variable existance.
Already mentioned that C++ doesn't provide such facility.
On the other hand there are cases where the OS implement mechanisms close to isDefined(),
like the GetProcAddress Function, on Windows.
No. It's not like you have a runtime system around C++ which keeps remembers variables with names in some sort of table (meta data) and lets you access a variable through a dynamically generated string. If you want this, you have to build it yourself, for example using a std::map that maps strings to some objects.
Some compile-time mechanism would fit into the language. But I don't think that it would be any useful.
In order to achieve this first you need to implement a dynamic variable handling system, or at least find some on the internet. As previously mentioned the C++ is designed to be a native language so there are no built-in facilities to do this.
What I can suggest for the most easy solution to create a std::map with string keys storing global variables of interest with a boost::any, wxVariant or something similar, and store your variables in this map. You can make your life a bit easier with a little preprocessor directive to define a variables by their name, so you don't need to retype the name of the variable twice. Also, to make life easier I suggest to create a little inline function which access this variable map, and checks if the given string key is contained by the map.
There are implementation such a functionality in many places, the runtime property handling systems are available in different fashion, but if you need just this functionality I suggest to implement by yourself, because most of these solutions are quite general what you probably don't need.
You can make such function, but it wouldn't operate strings. You would have to send variable name. Such a function would try to add 0 to the variable. If it doesn't exists, an error would occur, so you might want to try to make exception handling with try...throw...catch . But because I'm on the phone, I don't know if this wouldn't throw an error anyways when trying to send non-existing variable to the function...