Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/GrammaTech/clang-mutate
Manipulate C-family ASTs with Clang
https://github.com/GrammaTech/clang-mutate
Last synced: 11 days ago
JSON representation
Manipulate C-family ASTs with Clang
- Host: GitHub
- URL: https://github.com/GrammaTech/clang-mutate
- Owner: GrammaTech
- License: other
- Created: 2017-12-01T22:31:41.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2018-10-22T23:47:00.000Z (about 6 years ago)
- Last Synced: 2024-08-02T01:25:38.881Z (4 months ago)
- Language: C++
- Homepage:
- Size: 2.17 MB
- Stars: 63
- Watchers: 13
- Forks: 6
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: COPYING
Awesome Lists containing this project
README
# clang-mutate: Manipulate C-family ASTs with Clang
This tool provides an interface for performing operations on C and C++
source files. Using the
[clang LibTooling interface](http://clang.llvm.org/docs/LibTooling.html),
it obtains an abstract syntax tree (AST) representation of the source
and provides enables the inspection or alteration the source ASTs.## Installation
`clang-mutate` is dependent on
[clang/llvm version 6.0.X](http://releases.llvm.org/download.html).
Precompiled binaries may be downloaded for the platform of your choice;
once downloaded, ensure `clang` is on your $PATH.Beyond clang, we use `zlib` and `tinfo`. Additionally, we use
`pandoc` to generate documentation. These
tools may be installed via the package manager of your choice.
On Debian systems, `sudo apt-get install libtinfo-dev zlib1g-dev pandoc`
will install these dependencies.## Inspection operations
`clang-mutate` can output the ASTs for input source file(s) formatted
either as JSON or S-expressions. Output ASTs provide source
information to enable subsequent source rewriting by external tools.
Alternatively, it can be launched in interactive mode, and ASTs can be
explored in a plain text format more similar to source code.Some of the inspection operations are:
`-annotate`
: Display the source, annotating statements with their IDs
and AST classes`-ids`
: Display the number of statements in the source`-list`
: List every statement's ID, AST class, and range`-number`
: Display the source, annotating statements with their IDs`-number-full`
: Display the source, annotating full statements with their IDs`-cfg`
: Include control-flow information in ASTsRefer to the [manual](man/clang-mutate.template.md) for complete
documentation of available commands.## Mutation operands
In `clang-mutate`, the mutation operands and operators are specified
as separate flags. The `stmt1` and `stmt2` operands are used to
specify a numeric AST ID to which an operator will be applied. The
`value1` and `value2` operands are strings, and the `file1` and
`file2` operands may be used to specify a file whose contents will be
used as the strings for `value1` and `value2`, repectively.## Mutation operations
Some of the mutation operations that are available include:
`-cut`
: Cut `stmt1` from the source`-insert`
: Insert `value1` before `stmt1``-set`
: Set the text of `stmt1` to `value1``-swap`
: Swap `stmt1` and `stmt2` in the sourceRefer to the [manual](man/clang-mutate.template.md) for complete
documentation of available mutation commands.## Installation
As mentioned above, `clang-mutate` uses the clang LibTooling
interface, which means that the `clang-mutate` executable works best
when run from the same directory as clang. Run "make install" to build
and install.A PKGBUILD file is provided for installation on Arch Linux systems.
`clang-mutate` has only been tested on Linux, although we don't know
of any reason it should not work in other OSes. If you encounter
issues running in a different OS, please let us know by filing an
issue report or a merge request. We're happy to incorporate changes
that will enable more general execution.## Examples
A running example using the file `etc/hello.c`. Here is the source:
$ cat etc/hello.c
#include
int main(int argc, char *argv[])
{
puts("hello");
return 0;
}Count the number of statements:
$ clang-mutate -ids etc/hello.c --
12Print the source, annotated with statement IDs:
$ clang-mutate -number etc/hello.c --
#include
/* 0.1[ */int main(/* 0.2[ */int argc,/* ]0.2 */ /* 0.3[ */char *argv[]/* ]0.3 */)
/* 0.4[ */{
/* 0.5[ *//* 0.6[ *//* 0.7[ */puts/* ]0.7 *//* ]0.6 */(/* 0.8[ *//* 0.9[ *//* 0.10[ */"hello"/* ]0.10 *//* ]0.9 *//* ]0.8 */);/* ]0.5 */
/* 0.11[ */return /* 0.12[ */0/* ]0.12 */;/* ]0.11 */
}/* ]0.4 */
/* ]0.1 */Cut the return statement:
$ clang-mutate -cut -stmt1=11 etc/hello.c --
#include
int main(int argc, char *argv[])
{
puts("hello");}
Replace the string "hello" with the string "good bye":
$ clang-mutate -set -stmt1=9 -value1='"good bye"' etc/hello.c --
#include
int main(int argc, char *argv[])
{
puts("good bye");
return 0;
}Use the `tools/perforate-loops` script to halve the number of loop iterations by
replacing `++` or `--` with `+=2` or `-=2`, respectively:$ make etc/loop
cc etc/loop.c -o etc/loop
$ ./etc/loop
hello 0 10
hello 1 9
hello 2 8
hello 3 7
hello 4 6
hello 5 5
hello 6 4
hello 7 3
hello 8 2
hello 9 1$ ./tools/perforate-loops etc/loop.c > /tmp/faster.c
$ make /tmp/faster
cc /tmp/faster.c -o /tmp/faster
$ /tmp/faster
hello 0 10
hello 2 8
hello 4 6
hello 6 4
hello 8 2Use the `tools/strings-to` script to replace string literals:
$ ./tools/strings-to etc/hello.c foo
#include
int main(int argc, char *argv[])
{
puts("foo");
return 0;
}