| # Clang Spanification tool |
| |
| This tool generates cross-translation unit rewrites converting pointer type expressions (T*/raw_ptr<T>) to base::span<T>/base::raw_span<T> expressions. |
| |
| For instance: |
| ```cpp |
| std::vector<int> ctn = {1,2,3, 4}; |
| ... |
| int* ptr = ctn.data(); |
| ... |
| ptr[index] = value; |
| ``` |
| ptr here becomes a span, and the code becomes: |
| |
| ```cpp |
| std::vector<int> ctn = {1,2,3, 4}; |
| ... |
| base::span<int> ptr = ctn; |
| ... |
| ptr[index] = value; |
| ``` |
| |
| ## Build |
| |
| Clang is built using CMake. To run cmake, this script can be used: |
| ```bash |
| ./tools/clang/scripts/build.py \ |
| --without-android \ |
| --without-fuchsia \ |
| --extra-tools spanify |
| ``` |
| |
| The build directory is created into: `third_party/llvm-build/Release+Asserts/` |
| and you can build it again incrementally using: |
| ```bash |
| ninja -C third_party/llvm-build/Release+Asserts/ spanify |
| ``` |
| |
| |
| ## Run the tests |
| |
| ```bash |
| ./tools/clang/spanify/tests/run_all_tests.py |
| ``` |
| |
| ### Troubleshooting |
| |
| You will need to have the `python` binary reachable from your path to run the |
| tests. You can route `python3` to just `python` with the following install. |
| |
| ```bash |
| sudo apt install python-is-python3 |
| ``` |
| |
| Finally you need to have a version of libstdc++ installed. If you see errors |
| like: |
| ```bash |
| Failed to process deref-expr-actual.cc |
| tools/clang/spanify/tests/deref-expr-actual.cc:4:10: fatal error: 'vector' file not found |
| 4 | #include <vector> |
| | ^~~~~~~~ |
| 1 error generated. |
| ``` |
| |
| You can install libstdc++ as follows: |
| ```bash |
| sudo apt install libstdc++-14-dev |
| ``` |
| |
| ## Using the tool |
| |
| The `rewrite-multiple-platforms.sh` scripts first builds the tool, runs tests |
| and then runs the tool over every configuration in the list of platforms. |
| |
| ```bash |
| ./tools/clang/spanify/rewrite-multiple-platforms.sh |
| ``` |
| |
| ### Hints |
| |
| #### Flags |
| |
| 1. `--platforms=<comma,separated,list,of,platforms>` |
| 2. `--skip-building-clang` or `-b` for short, only use if you have already built |
| clang and know nothing has changed, this implicitly adds `--keep-build` flag, |
| see the flag definition below for more details on its behaviour. |
| 3. `--skip-rewrite` or `-r` for short, if you've already ran on the platform and |
| have the associated `~/scratch` directory you can just skip generating this. |
| 4. `--skip-extract-edits` or `-e` for short, don't attempt to run |
| `extract_edits.py` on the results of the rewrite. |
| 5. `--keep-build` when you plan to run again (and want to use |
| `--skip-building-clang`), you first need a run that completed the build part |
| with `--keep-build`. IMPORTANT: this will mean `third_party/llvm-build` will |
| not be the normal optimized build and will slow down your regular chromium. |
| You should restore it by running |
| `mv third_party/llvm-build-upstream third_party/llvm-build` or running the |
| script without `--keep-build` |
| 6. `--incremental-clang-build` or `-i` for short, will use the already built |
| clang and attempt to only incrementally include changes to the clang plugin, |
| this implicitly adds `--keep-build` flag, see the flag definition above for |
| more details on its behaviour. |
| |
| The flags are useful to cut down iteration time when working on particular |
| parts. If you are modifying the plugin you can't skip the build part, but if you |
| just want to do a new platform this flag is useful. If you've already done the |
| platform, skipping both the build and the rewrite allows you to work on |
| `extract_edits.py`'s logic. Skipping edits is only really useful if you are |
| testing early steps and you aren't interested in the script even attempting the |
| edits (so it ends earlier). |
| |
| Example commands: |
| |
| ```bash |
| |
| ./tools/clang/spanify/rewrite-multiple-platforms.sh --platforms=linux |
| ./tools/clang/spanify/rewrite-multiple-platforms.sh -p=linux --keep-build |
| ./tools/clang/spanify/rewrite-multiple-platforms.sh --skip-building-clang |
| ./tools/clang/spanify/rewrite-multiple-platforms.sh --b |
| ./tools/clang/spanify/rewrite-multiple-platforms.sh \ |
| --platforms=linux --skip-building-clang --skip-rewrite |
| ``` |
| |
| ### Troubleshooting |
| |
| If for some reason your `rewrite-multiple-platforms.sh` command fails, it is |
| important to restore the "normal" state of your clang directory before running |
| again. As the script starts to run, if you are building clang it does a |
| `mv third_party/llvm-build third_party/llvm-build-upstream` and will (if it runs |
| successfully) restore it with the inverse |
| `mv third_party/llvm-build-upstream third_party/llvm-build` at the end of its |
| execution. However if you encounter an error or use `Ctrl-C` on the script, this |
| won't happen and you might see an error saying that |
| `mv: cannot overwrite 'third_party/llvm-build-upstream/llvm-build': Directory not empty`. |
| To fix this simply move the saved directory back to its original spot and then |
| run the script again. |
| |
| ```bash |
| mv third_party/llvm-build-upstream third_party/llvm-build |
| ``` |
| |
| Another possible issue is during the `extract_edits.py` step it might complain |
| that `~/scratch/rewriter.main.out` doesn't exist. This can happen sometimes |
| because the script writes out files to `~/scratch/rewriter-$PLATFORM.main.out` |
| and then later uses `cat platform_file >> ~/scratch/rewriter.main.out` and it |
| can be unreliable due to the large file size. You can simply create it yourself |
| either by appending each platform together or symlinking it together. |