Where to find "-o" ("--output") argument in Clang/LLVM? - llvm

I'm writing a custom LLVM analysis pass and want to output a simple CSV file in the pass's do_finalization method. I'd like to name the CSV file based on the desired output filename passed to Clang/LLVM, but I can't find this value.
For example, if I compile with:
clang -o test test.c
I'd like to output test.csv (or more generally <output filename>.csv). Where do I find the value test?

It's defined in
lib/TableGen/Main.cpp
static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"),
cl::value_desc("filename"),
cl::init("-"));
You can define a command option in your analysis pass, and take the value as the output file name.

You can use cl::getRegisteredOptions to grab a cl::Option* pointer and downcast it to the type the option is declared with:
std::string &OutputFilename () {
auto *option = static_cast<llvm::cl::opt<std::string>*>(
llvm::cl::getRegisteredOptions().lookup("o"));
return option->getValue();
}
This will return the value of -o specified on the command line or "-" if the standard output is used.
The usual precautions about type-unsafety apply.

Related

finding line number of end of a function

I am trying to automate some debug by printing inputs and outputs of a function via GDB, when that function hits. To enable setting breakpoints at these places, I am doing the following.
I am working with templates, and rbreak :. does not hit the breakpoints at the functions in my file. So i extract line numbers of functions from the executable as follows.
With the executable, extract the linenumber of start of a function;
nm a.out | grep "className" | grep "functionName" | grep " t " | addr2line -e a.out -f | grep "cpp" | uniq
-> this outputs the filename:linenumber
add these contents to a .gdb file with a "b prefix"
Query - how can we extract the line number of a end of a function from the executable ?
With this info, I can add it to the GDB script, the final script would
look something like below. this script would be loaded into GDB before
the execution of the program.
b filepath:<startline of function>
commands
print input1 input2 etc
continue
end
b filepath:<endline of function>
commands
print output1 output2 etc
continue
end
It remains to find only the end line of a given function belonging to a class/file, given the executable and start line of the function
I also considered using GDBs finish command but the control is back to the caller already.
it would be easy to have the prints within the called function instead of the caller, so that we can monitor input/outputs of every call of the function.
This will simplify my debug to a large extent.
Any suggestion/comments is highly appreciated.
Thanks a lot in advance !!
First, notice that template functions are not functions, but actually recipes. When you use a template the compiler generates a function from the template.
If you want to use the break command then you need the full function name. For instance, the template below
template <typename T>
inline T doubleInput(const T& x) {
return 2 * x;
}
will become the function doubleInput<int> when you pass an int, doubleInput<double> when you pass a double, etc. You need the whole name including the <type> part to add a breakpoint with the break command and even in that case it will only stop in that particular case of the template.
But the rbreak command does work with templates. If you write in gdb rbreak doubleInput* then a breakpoint will be added in all existing specializations of the template.
See the answer in this question.
I don't know if gdb nowadays has the feature to add a breakpoint in the return of a function, but answers in the nine years old question provide some possibilities, including a custom python command to find and add a breakpoint to the retq instructions or using reverse debugging. I haven't tried these options.

Prettify clang -v output

Is there any way to get clang output to insert carriage returns? When compiling with the verbose option, I just get these huge unreadable dumps of compiler flags and paths.
Use popen to start your clang session. Create a new command line as clang -v (including the space) and concatenate the arguments that you usually feed to clang itself. After the final argument, add 2>&1 to convert Clang's stderr output to regular stdout so popen can pick it up. Then loop over popen's input and parse each separate line, adding extra information where you see fit.
As an example, I grabbed the entire set of flags for my local Clang using
clang -cc1 --help
and incorporated this as a single long string in my C program. Then I looped over the return results from popen, scanning for flags starting with -, and when one was found, I scanned the long flags string for this. If it found something, I write it out on a separate line in green (using ANSI escape sequences). Then I test the flags string if an argument should follow – these usually have a leading <...> indicator. If so, I write it out in blue. Finally, I write out the entire flag explanation line until I encounter an end-of-line.
With my very rough program called colorclang – 123 lines of actual code – I get output like this:
As it is, it tests every input line for possible flags so there is some mis-coloring. More exact parsing is possible; I'd have to add separate routines for the single line starting with "/usr/bin/clang" (for the common Clang flags), the single line starting with "/usr/bin/ld" (and parse the loader flags), and possibly the lines after each #include .. statement.
Pieced together with the help of Complete list of clang flags?, Steve Kemp's answer to C: Run a System Command and Get Output?, and after deducing clang -v writes to stderr, larsman's answer to c popen won't catch stderr.

boost::program_options: option recognizes following option as an argument when no argument is provided

I have a program that takes a few options and I want to recognize when no argument is provided.
This is what happen when I call my program without one option arg
program -lib
cout: the required argument for option '-lib' is missing
That's ok, but when I call my program with additional options, e.g
program -lib -out number
The variable assigned to lib gets the value "-out", although -out was declared as an option. I expect to get the same warning as in the first example.
I can solve this problem by adding a custom notifier to all the options, code below:
void validate_string(const std::string& r)
{
if (*r.begin() == '-') {
throw Something
}
}
...
("lib", po::value<std::string>(&lib)->notifier(validate_string), "Library")
There's any way of doing this with a build-in mechanism of boost::program_options? I don't like my current solution, the options declaration look messy and is hard to read. Besides -out is not getting assigned.
BTW: I'm using allow_long_disguise, so single - is allowed for long options

gengetopt: How to parse a string without an option (like a file name)

I'm trying to parse command line options using code generated by gengetopt, and I'm trying to figure out how to parse an extra argument (after all the other options) that has no long or short option.
I'd like to call it like this:
program [options] [input file]
ex:
program -a -b -letterc "C:\somefile.txt"
or
program -a -b -letterc somefile.txt
where the option "letterc" has no arguments.
Does anyone know how to do this using gengetopt?
These should be avaiable in the inputs member of the gengetopt_args_info. There are input_num of them.

Run the same C++ Program from different Binary Names

Okay, for a homework assignment my professor wants us to write a program in C++ that converts from miles to km. I did all that, the program runs. However, he has this special way of calling the program:
The program's usage options are based
on the NAME of the BINARY FILE. If
the program name is 'km2miles', the
program interprets the command line
argument as a kilometer value to
convert to miles. If the name is
'miles2km', then it interprets as
miles being converted to km. Since the
first command line argument, argv[0]
is always the program's name, you can
use its value to decide which function
to call.
I only have 3 files in this project (he tells us to ONLY have these 3):
convert.cpp
distance.cpp
distance.h
Distance .h and .cpp have the different functions to convert Mi to Km and Vice Versa, the convert.cpp has the main function. However, the only way I know how to call this program (after compiling it) is to say:
./convert 10
Where 10 is the number to convert. He says it should be called like this:
$ km2miles 100
and
$ miles2km 60
I have no idea how to get the program to act differently by having a different name... especially when that name doesn't even run the program! Help would be appreciated.
You can:
specify a name when you build it, and build it twice
on Windows: copy convert miles2kms; copy convert kms2miles
on UNIX/Linux: cp convert miles2kms; cp convert kms2miles
on UNIX/Linx (better): make a link or symbolic link: ln -s convert miles2kms; ln -s convert kms2miles.
Inside your program, you should be doing something like:
#include <string>
#include <iostream>
int main(int argc, const char* argv[])
{
std::string program_name = argv[0];
if (argc != 2) {
std::cerr << "usage: " << program_name << " <value>\n";
return 0;
}
if (/* TODO: what would go here? */)
...
else
...
}
The instructions already tell you how:
Since the first command line argument, argv[0] is always the program's name, you can use its value to decide which function to call.
especially when that name doesn't even run the program!
If you're using gcc, by default it generates a binary named a.out, but you can rename it to be whatever you want. (Or you can specify the name of the output file via the -o command-line option.)
Well, he gave you one clue with the argv[0] thing.
Did you perhaps discuss symbolic links at some point in your class?
Difficult for me to give more hints without actually giving away the answer.
If you don't want to recompile the same code into 2 different executable files then you may need to use a symbolic link:
http://en.wikipedia.org/wiki/Symbolic_link