Given a program like this:
int gcd(para) {...}
int main() {
...
int a = gcd(para1);
int b = gcd(para2);
return 1;
}
I want to instrument the code and print the function names that will be executed in order: i.e., main(), gcd(), gcd().
The problem is I don't know how to pass the function name as argument to helper function.
I wrote following:
For helper function:
I use: void printDynamicFuncName(char* FName) {}
For pass:
I use:
Type* Int8 = Type::getInt8PtrTy(context);
Function *CalleeF = cast<Function>(F.getParent()->getOrInsertFunction("_Z20printDynamicFuncNamePc", Void, Int8, NULL));
Constant* arg = ConstantDataArray::getString(context, F.getName());
Builder.CreateCall(CalleeF, arg);
I got it myself!
I could use:
Type* Int8 = Type::getInt8PtrTy(context);
static IRBuilder<> Builder(context);
Instruction *I = &*inst_begin(F);
Function *CalleeF = cast<Function>(F.getParent() ->getOrInsertFunction("_Z20printDynamicFuncNamePc", Void, Int8, NULL));
Builder.SetInsertPoint(I);
Builder.CreateCall(CalleeF, Builder.CreateGlobalStringPtr(F.getName()), "");
While in the helper function:
void printDynamicFuncName(char* FName) {
errs() << "Function Name is " << FName << "\n";
}
Related
Suppose I analyze binary operations, and use llvm to easily perform static analysis to get the operators and operands of binary operations. But if I want to get the specific value of the runtime operand and print it out, can I use the CallInst:: Create method to achieve it, or what other method
I tried to use function instrumentation. In the process of each binary operation of Pass, I inserted the function in front of this binary operator, but I did not get the output. Suppose I print only the number of rows and columns first.
bool Instrument::runOnFunction(Function &F) {
auto FunctionName = F.getName().str();
outs() << "Running " << PASS_DESC << " on function " << FunctionName << "\n";
outs() << "Instrument Instructions\n";
LLVMContext &Context = F.getContext();
Module *M = F.getParent();
Type *VoidType = Type::getVoidTy(Context);
Type *Int32Type = Type::getInt32Ty(Context);
Type *Int8Type = Type::getInt8Ty(Context);
M->getOrInsertFunction(COVERAGE_FUNCTION_NAME, VoidType, Int32Type,
Int32Type);
M->getOrInsertFunction(BINOP_OPERANDS_FUNCTION_NAME, VoidType, Int8Type,
Int32Type, Int32Type, Int32Type, Int32Type);
for (inst_iterator Iter = inst_begin(F), E = inst_end(F); Iter != E; ++Iter) {
Instruction &Inst = (*Iter);
llvm::DebugLoc DebugLoc = Inst.getDebugLoc();
if (!DebugLoc) {
continue;
}
int Line = DebugLoc.getLine();
int Col = DebugLoc.getCol();
instrumentCoverage(M, Inst, Line, Col);
}
return true;
}
void __coverage__(int line, int col) {
printf("%d, %d\n",line,col);
}
void instrumentCoverage(Module *M, Instruction &I, int Line, int Col) {
auto &Context = M->getContext();
auto *Int32Type = Type::getInt32Ty(Context);
auto LineVal = ConstantInt::get(Int32Type, Line);
auto ColVal = ConstantInt::get(Int32Type, Col);
std::vector<Value *> Args = {LineVal, ColVal};
auto *CoverageFunction = M->getFunction("__coverage__");
CallInst::Create(CoverageFunction, Args, "", &I);
}```
For my program (C++), I need to read one of the function parameter as it is given while calling the function, for example:
void foo(int arg)
{
// I need to read the "arg" parameter here, not its value but the exact thing passed while calling the "foo" function
}
for example:
int bar = 10;
foo(bar); // I want to read "bar" string
Is there a way to do that?
One of the alternate option I can see is make two parameters and call the function like:
foo(bar, "bar");
I'm a beginner in c++, so it may be a silly question...
AS there is no build-in reflection in C++, in resulting code all ids will be gone. But you can emulate it by using stringize operator #, if you don't mind to use some wrappers. assert() macro in some implementations makes use of it.
#include <iostream>
void order(int arg1, int arg2, const char* str)
{
std::cout << str << arg1*arg2 << std::endl;
}
#define REFLECT_INVOKE(func, ...) (func)(__VA_ARGS__, #func "(" #__VA_ARGS__ ") = ")
int main()
{
int x = 6;
int y = 11;
REFLECT_INVOKE(order,x,y);
}
Output:
order(x,y) = 66
Operator # literally wraps following token in quotes before placing result into processed source before compilation, so statement REFLECT_INVOKE(order,x,y); is processed into (order)(x,y,"order" "(" "x,y" ") = ");
We can make it a bit more universal, using new features (there is probably simple and obvious way to do this):
int order(int arg1, int arg2)
{
return arg1*arg2;
}
template<class F, class ...Args>
auto debug_call( F func, const char* str, Args... args) ->
decltype(std::forward<F>(func)(std::forward<Args>(args)...))
{
if constexpr ( std::is_same<decltype(std::forward<F>(func)(std::forward<Args>(args)...)),void>::value) {
std::cout << str;
func(args...);
} else {
auto res = func(args...);
std::cout << str << "= " << res;
return res;
}
}
#define REFLECT_INVOKE(func, ...) (debug_call)(func, #func "(" #__VA_ARGS__ ") ", __VA_ARGS__)
int main()
{
int x = 6;
int y = 11;
REFLECT_INVOKE(order,x,y);
}
This is barely usable outside of debugging purposes.
I would like the function to return different types depending on different parameter values, but how can I print the variable the void pointer points to
in main()?
#include <iostream>
#include <string>
using namespace std;
void * func(int a)
{
if (a == 1)
{
int param = 5;
return ¶m;
}
else if (a == 2)
{
double param = 5.5;
return ¶m;
}
else if (a == 3)
{
string param = "hello";
return ¶m;
}
else
{
return nullptr;
}
}
int main()
{
void *ptr = func(3);//
cout << ptr;// print the address not the value
getchar();
return 0;
}
param is an automatic variable. You cannot return it and use it outside its scope.
param exists only within func, if you return it, the result is Undefined Behaviour.
To fix it you can either:
allocate param on the heap dynamically. After you do that, you can safely return param address but you have to remember to free it when you don't need it.
Here is correction of your code
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
void * func(int a)
{
if (a == 1)
{
int *param = new int(5);
return param;
}
else if (a == 2)
{
double *param = new double(5.5);
return param;
}
else if (a == 3)
{
char *param = new char[50];
strcpy(param, "test");
return param;
}
return nullptr;
}
int main()
{
int *ptr = (int*)func(1);
cout << *ptr << std::endl; // print the int value
delete ptr;
double *ptr2 = (double*)func(2);
cout << *ptr2 << std::endl; // print the double value
delete ptr2;
char *ptr3 = (char*)func(3);
cout << ptr3 << std::endl; // print the string
delete[] ptr3;
getchar();
return 0;
}
If you can use C++17, you can easily solve it by using a std::variant instead of a void *:
#include<iostream>
#include<string>
#include<variant>
std::variant<int, double, std::string, void *> func(int a) {
if (a == 1) {
int param = 5;
return param;
} else if (a == 2) {
double param = 5.5;
return param;
} else if (a == 3) {
std::string param = "hello";
return param;
} else {
return nullptr;
}
}
int main() {
std::visit([](auto v) {
std::cout << v << std::endl;
}, func(3));
}
See it up and running on wandbox.
In C++11/14 you can do the same with a tagged union. The basic idea is that what you return contains enough information so that the caller can get out of it the original type.
Alternatives exist.
As an example, you could erase the type and return a pair that contains both the original (erased) variable and a pointer to function filled with an instantiation of a function template. The latter will be able to reconstruct the original variable from a void * for it knows its type.
Well, pretty much a great machinery you can avoid to use with a tagged union or a std::variant (more or less a type-safe version of a tagged union at the end of the day).
What you're returning is the address of a local variable. That variable goes out of scope when the function returns, meaning that the memory it was using could be reused. Attempting to dereference that pointer (i.e. access the memory it points to) invokes undefined behavior.
Even if you were returning a valid pointer, the fact that your function returns a void * means that any type information regarding what that pointer was pointing to is lost. You could print one or more bytes starting at that address, but it won't tell you what the original type was.
Even if that pointer were valid, you simply can't have enough information to force safely a cast to something and then print it.
No information of its size, no information of its internal layout. So,you simply can not print what's pointed by a void*, unless you have some information prepared by hand somewhere, and force a static_cast to the known type.
For example:
double x = 1.2;
int y = 5;
int f(void** output) {
static int x;
if ( x++ ) {
*output = &x;
return 1;
}
*output = &y;
return 2;
}
...
void* out;
int r = f(&out);
if ( r == 1 ) cout << *(static_cast<double*>(out));
else if ( r == 2 ) cout << *(static_cast<int*>(out));
Apologies in advance the possibly vague Title, best I could come up with.
I have the following C++ and text file:
cpp file:
class Test
{
int var1;
int var2;
public:
bool set_var1();
bool set_var1();
bool set(string var_name);
void process_file();
}
text file:
var1 value1
var2 value2
Objective - In process_file(), read/parse the text file, and for each varX in file call the corresponding set_varX().
One option, in function set(), compare var_name to "var1" / "var2" / etc, and
call corresponding set_varX(). The issue I have with this approach, as more
lines are added to the text file, the code becomes...ugly, with the long "if-else"
code block in set().
Another option, create a static map
"var1" set_var1()
"var2" set_var2()
set() will iterate over the map, and upon a string compare match call the corresponding func_ptr. This option requires maintaining a map structure.
Though I prefer the second option, less code changes as the test file increases, is there another option. Just thinking out loud, in set(), can I take the string var_name, and prepend set_, and call set_var_name(), basically somehow avoid the string compare, which is done in both the cases above. My gut feeling, in C++, that is not possible to do during runtime
Thank you,
Ahmed.
It sounds like you're asking about reflection, which is not a feature of C++, so this won't be possible. As you pointed out there are solutions to the problem, but all of them will involve a mapping of string names to functions, and you'll have to construct/maintain that mapping yourself. The language won't do this for you.
You can improve option 2 by making var1, var2.. self registering types. New keywords cause no code changes, only new types. Therefor the map has to be some kind of global object, singleton etc.
A very simple example:
struct Setter
{
virtual ~Setter() = default;
virtual void Process(std::string content) const = 0;
};
class SetterMap
{
public:
bool RegisterSetter(std::string keyword, std::unique_ptr<Setter> setter) {
setters[keyword] = move(setter);
return true;
}
const Setter& GetSetter(const std::string& keyword) const {
return *(setters.at(keyword));
}
private:
std::map<std::string, std::unique_ptr<Setter>> setters;
};
inline SetterMap& GetSetterMap() {
static SetterMap map;
return map;
}
Define and register some setters:
struct Var1 : Setter {
void Process(std::string content) const override {
}
};
namespace {
bool var1registered = GetSetterMap().RegisterSetter(
"var1", std::make_unique<Var1>());
}
struct Var2 : Setter {
void Process(std::string content) const override {
}
};
namespace {
bool var2registered = GetSetterMap().RegisterSetter(
"var2", std::make_unique<Var2>());
}
Use the setter map:
int main()
{
std::string line = "var1: blablab";
GetSetterMap().GetSetter("var1").Process(line);
}
Depending on your needs, you might consider embedding Lua and changing the syntax of the text file to something like:
test.var1 = 1234
test.var2 = 42
Here, test would be a global Lua table that you instantiate from the C++ side and assign a metatable to using lua_setmetatable(). The metatable would have a __newindex method as described here. If you're familiar with Python, this is sort of like providing a __setattr__ metamethod—i.e., it intercepts assignment of non-existent fields and executes some user-specified magic.
The 'trick' in your case is to create a metatable in Lua that re-routes access to the var1, var2, etc. fields of test to a lua_CFunction wrapper that sets the corresponding field on the underlying Test object. After that, you can simply 'run' the file using luaL_dofile().
A quick-n-dirty example (tested against Lua 5.1.5) that illustrates the gist of the idea is appended below. (It needs to be compiled with -std=c++11 due to the use of a raw string literal.)
This approach is certainly overkill if your needs are very specific/targeted. However, if you want/need scripting in your app, anyway, embedding Lua is a great solution.
NOTE: It is not strictly required to use a separate table (e.g., test in the example). Lua stores global variables in a table named _G, so you could instead set a metatable for _G. However, doing so is a bit of a hack; it makes the example harder to follow, and would limit some of the other ways you can use Lua in your host application.
#include <cassert>
#include <iostream>
#include <string>
#include <cstdlib>
#include <lua.hpp>
static const char* regkey = "Test";
class Test
{
public:
Test();
virtual ~Test();
void set_var1(int value);
void set_var2(int value);
void process_file(std::string const& filepath);
private:
int var1, var2;
lua_State* L_;
};
static int set_var(lua_State* L)
{
// Get the table, key and value
std::string key = lua_tostring(L, 1);
int value = lua_tointeger(L, 2);
// Get the Test instance pointer from the Lua registry
lua_pushlightuserdata(L, (void*)regkey);
lua_gettable(L, LUA_REGISTRYINDEX);
Test* test = (Test*) lua_touserdata(L, -1);
// Execute set_XXX() as appropriate
if (test == NULL) {
std::cerr << "Pointer in registry is missing or NULL, aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
if (key == "var1") {
test->set_var1(value);
}
else if (key == "var2") {
test->set_var2(value);
}
else {
std::string errmsg = "No such variable '" + key + "'";
lua_pushstring(L, errmsg.c_str());
lua_error(L);
}
return 0;
}
Test::Test()
{
L_ = luaL_newstate();
assert(L_);
luaL_openlibs(L_);
// Point the Lua global '_set_var' at our C set_var() function
lua_pushcfunction(L_, &set_var);
lua_setglobal(L_, "_set_var");
// Store our `this' pointer in the Lua registry
lua_pushlightuserdata(L_, (void*)regkey);
lua_pushlightuserdata(L_, this);
lua_settable(L_, LUA_REGISTRYINDEX);
// Set up the metatable to re-route "foo = X" to "_set_var('foo', X)"
std::string script = R"SCRIPT(
test = {}
local mt = {}
mt.__newindex = function(tbl, key, value)
_set_var(key, value)
end
setmetatable(test, mt)
)SCRIPT";
int retval = luaL_dostring(L_, script.c_str());
if (retval != 0) {
std::cerr << "luaL_dostring() failed (\""
<< lua_tostring(L_, -1)
<< "\"), aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
}
Test::~Test()
{
lua_close(L_);
}
void Test::set_var1(int value)
{
std::cout << "Setting var1 to " << value << std::endl;
var1 = value;
}
void Test::set_var2(int value)
{
std::cout << "Setting var2 to " << value << std::endl;
var2 = value;
}
void Test::process_file(std::string const& filepath)
{
int retval = luaL_dofile(L_, filepath.c_str());
if (retval != 0) {
std::cerr << "luaL_dofile() failed (\""
<< lua_tostring(L_, -1)
<< "\"), aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
}
int main()
{
Test().process_file("config.ini");
return 0;
}
I was wondering if in C/C++ language it is possible to pass arguments to function in key-value form.
For example in python you can do:
def some_function(arg0 = "default_value", arg1):
# (...)
value1 = "passed_value"
some_function(arg1 = value1)
So the alternative code in C could look like this:
void some_function(char *arg0 = "default_value", char *arg1)
{
;
}
int main()
{
char *value1 = "passed_value";
some_function(arg1 = value1);
return(0);
}
So the arguments to use in some_function would be:
arg0 = "default_value"
arg1 = "passed_value"
Any ideas?
Here's a C99 solution using compound literals and variadic macros:
#include <stdio.h>
#define some_func(...) some_func_((struct some_func_args_){ __VA_ARGS__ })
struct some_func_args_
{
const char *arg1;
const char *arg2;
};
static void some_func_(struct some_func_args_ args)
{
if(!args.arg1) args.arg1 = "default";
printf("---\narg1 = %s\narg2 = %s\n", args.arg1, args.arg2);
}
int main(void)
{
some_func("foo", "bar");
some_func(.arg1 = "spam");
some_func(.arg2 = "eggs");
return 0;
}
You can emulate this in C++ with this:
struct params {
string foo_;
double bar_;
short xxx_;
params() : foo_("123"), bar_(3.1415), xxx_(42) {} // default parameters
params& foo(string s) {foo_=s;return *this;}
params& bar(double x) {bar_=x;return *this;}
params& xxx(short x) {xxx_=x;return *this;}
};
void some_function(params const & p);
int main() {
some_function(params().bar(99.9).xxx(23));
}
But IMHO it's not worth the effort. Too much boiler plate.
If I remember correctly Stroustrup's book "Design and Evolution of C++" contains a section that discusses this feature request of "named arguments". The conclusion was something along the lines of: not a good idea. Check it out if you want details.
Named arguments are not supported in C, but you could emulate named parameters it using variadic function (though you loose type safety):
#include <stdarg.h>
void do_sth (int foo, ...)
{
int baz = 7; /* "baz" argument */
const char *xyz = "xyz"; /* "xyz" argument */
/* Parse named parameters */
va_list ap;
va_start (ap, foo);
for (;;) {
const char *key = va_arg (ap, char *);
if (key == NULL) {
/* Terminator */
break;
} else if (strcmp (key, "baz") == 0) {
baz = va_arg (ap, int);
} else if (strcmp (key, "xyz") == 0) {
xyz = va_arg (ap, char *);
} else {
/* Handle error */
}
}
va_end (ap);
/* do something useful */
}
do_sth (1, NULL); // no named parameters
do_sth (2, "baz", 12, NULL); // baz = 12
do_sth (3, "xyz", "foobaz", NULL); // xyz = "foobaz"
do_sth (4, "baz", 12, "xyz", "foobaz", NULL); // baz = 12, xyz = "foobaz"
Just remember to end optional arguments list with NULL. You could also use some ENUM as keys instead of character strings.
This technique is used, for exapmle, in GTK+:
gtk_list_store_set
gtk_message_dialog_new
This is not available in vanilla C or C++. However, there is a C++ Boost Library that lets you do this for functions you write: Boost.Parameter. To borrow one of their examples, its usage is sort of like this:
myclass x("bob", 3); // positional
myclass y(_index = 12, _name = "sally"); // named
myclass z("june"); // positional/defaulted
Implementing this for your functions does look somewhat involved, however. You may decide it isn't worth the effort.
No, you cannot pass parameters by name in C or C++.
Both languages support default arguments to the trailing parameters in a function. That is, any argument to a function may have a default value, but all subsequent arguments after the first default value is found must also have default values.
For example, the following are all valid:
void f(int a, int b = 0);
void g(double a = 1, double b = 2);
void h(int a = 3, int b = 2, int c = 1, int d = 0);
void i(float a, float b, float c = 1, float d = 2);
But the none of the following are valid:
void j(int a = 1, int b);
void k(int a, int b = 1, int c);
void l(int a = 2, int b = 1, int c);
The reason is simple: Since you cannot pass parameters by name in C and C++, the only way to know which parameters to use the defaults and which to use the passed values is by assigning the passed values to the parameters in order and then using the defaults (in order) for anything left over.
So, the following calls are valid using the functions above:
f(0); // calls f(0, 1);
g(); // calls g(1,2);
g(10); // calls g(10,2);
h(); // calls h(3,2,1,0);
h(1,2); // calls h(1,2,1,0);
#define call_foo(...) \
do { \
int first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
....
int main(void) {
call_foo(first=9, third=5, second=3);
}
Getting return values in a non-clunky manner is more difficult.
This would allow you to do very silly things (which I hate) such as specify default values for your arguments:
#define call_foo(...) \
do { \
int first = default_first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
This will fail if you do:
int first = 9;
call_foo(first=first, third=5, second=3);
because in the macro expansion the first=first will mean initialize the local first with itself. I thought about trying to get around this with preprocessor concatenation, but that gets more complicated. You would have to list the same number of macro parameters as function parameters.
#define call_foo(x, y , z) \
do { \
int call_foo_first; \
int call_foo_second; \
int call_foo_third; \
call_foo_##x; \
call_foo_##y; \
call_foo_##z; \
foo(call_foo_first, call_foo_second, call_foo_third); \
} while (0)
The call_foo_##x; line would turn into call_foo_first=first; if called in the previous example, so each symbol has it's own unique name.
This makes the default argument trick more awkward because you'd have to specify something to fill that spot in the macro argument list.
If the macro were defined with a default argument for first then:
call_foo(first, third=7, second=8);
This forces you to list all parameters (or at least something that results in legal C -- you could have listed second twice, but you could have done that anyway) in order use this macro.
I think you should be able to extend the last version of this for variable argument listed macros/functions, but the optional parameters would still have to be passed at the end of the list and you would have to use up all of the mandatory spots before you got to the optional arguments.
C++ only solution:
You could use boost::any, std::map and std::string to create an object with the posible arguments.
#include <iostream>
#include <map>
#include <string>
#include "boost/any.hpp"
using namespace std;
void variableArguments(map<string, boost::any> arguments){
cout << ">>> variableArguments begins" << endl;
if(arguments.find("intParameter") != arguments.end()){
cout << "Found int parameter: "
<< boost::any_cast<int>(arguments["intParameter"]) << endl;
}
if(arguments.find("stringParameter") != arguments.end()){
cout << "Found string parameter: "
<< boost::any_cast<string>(arguments["stringParameter"]) << endl;
}
cout << "<<< variableArguments ends" << endl;
}
int main(int argc, char *argv[])
{
map<string, boost::any> argMap;
argMap["intParameter"] = 5;
argMap["stringParameter"] = string("MyString");
variableArguments(argMap);
argMap.erase(argMap.find("intParameter"));
variableArguments(argMap);
return 0;
}