I am new to clang and need some help to rewrite c and c++ code for a custom coverage tool I am developing. As I understand it, I think I need to link to clang's libTooling to make a stand alone executable to make something like a code rewriter.
LLVM and clang are huge and it is difficult to know where to start. There are:
- AST matchers
- Source to Source tranformations.
- depth first RecursiveASTVisitor classes
that all appear to be doing something similar.
So far my best approach to rewriting some simple code was to follow an old tutorial tutorial and this 3 part tutorial - part 1.
as a simple example, I would like to be able to take some simple C code like the following:
#include <stdarg.h>
// example global function
int
foo(int* a, int *b) {
if (a[0] > 1) {
b[0] = 2;
} else if ((a[0] == 1) && (b[0] == 2)) {
b[0] = 3;
} else {
b[1] = -1;
}
a[0] = 2;
switch (a[0]) {
case 0:
case 1:
break;
case 2:
break;
default:
break;
}
return 3;
}
int main(int argc, const char **argv) {
int a[3] = {0};
int b[3] = {0};
return foo(a, b);
}
modify it something along the following lines (with the upper case code insertions):
#INCLUDE <CUSTOM_MACROS_AND_INLINES>
#include <stdarg.h>
// example global function
int
foo(int* a, int *b) {
_BREADCRUMB;
if (_BREADCRUMB(a[0] > 1)) {
b[0] = 2;
} else if (_BREADCRUMB(a[0] == 1) && _BREADCRUMB(b[0] == 2)) {
b[0] = 3;
} else {
b[1] = -1;
_BREADCRUMB;
return 1;
}
a[0] = 2;
switch (a[0]) {
case 0:
_BREADCRUMB
case 1:
_BREADCRUMB
break;
case 2:
_BREADCRUMB
break;
default:
_BREADCRUMB
break;
}
_BREADCRUMB;
return 3;
}
int main(int argc, const char **argv) {
_BREADCRUMB;
int a[3] = {0};
int b[3] = {0};
_BREADCRUMB;
return foo(a, b);
}
Using the RecursiveASTVisitor technique, I am finding it difficult to control where I can insert text into the rewritten output. Specifically trying to insert after the opening parenthesis of a function so I can drop the above breadcrumb strings into the rewritten code.