LDC contributor's guide
This page is a work-in-progress collection of tips for LDC contributors and development guidelines.
The LDC project uses two different CI systems: Travis CI, which does Ubuntu x86 + OS X builds, and AppVeyor, which does Windows builds. Both test LDC's branches and test pull requests too. Have a look at the build scripts in .travis.yml (Ubuntu Linux and OSX) and appveyor.yml (Windows).
Any efforts to get regular builds+tests on other platforms would be very much appreciated (especially non-x86 platforms, like ARM, PowerPC, ...).
To run the test suite locally, use ctest (e.g. ctest -j3 --output-on-failure) in the CMake root directory. To work on a specific test case, you might want to look into the -R and --verbose options to ctest.
Generally, use your good taste and try to use a style similar to the surrounding code. Many parts of the LLVM Coding Standards are directly applicable to LDC as well.
- Use clang-format with the LLVM style for formatting.
- Use include guards consistently, in the format LDC_<dir>_<filename>, e.g. LDC_GEN_DVALUE_H.
- Includes are placed at the top of the file, sorted lexicographically and grouped in the following order:
- Main include corresponding to the .cpp file, if any.
- DMD and other LDC includes.
- LLVM/libconfig includes.
- System includes.
APIs and idioms
- Avoid making changes to the front end sources (ddmd and dmd2) as much as reasonably possible. If modifications are necessary, be sure to enclose the deviations from the upstream source #if IN_LLVM blocks, and keep the original source code around for easier comparison. Add a comment referring to the relevant issue on our tracker, or the upstream DMD commit in case of a straight backport. This makes it much easier to resolve any merge conflicts when folding in new frontend releases.
- Use llvm_unreachable("message") instead of assert(0 && "message") (from llvm/Support/ErrorHandling.h). Not only might it lead to slightly better codegen, it also prevents »variable might be used uninitialized« and similar compiler warnings.
Tests are very important to prevent regressions. Upon fixing a bug, a test case should be added so that the bug stays fixed and doesn't come back by accident. Upon adding a new feature, extensive tests should be added that test all functionalities of that feature.
- Bug fixing often starts from a minimal test case, which is a good basis for the eventual test case that is added to the testsuite.
- Instead of creating tests after feature development, consider adding tests during feature development: it is a good way to solidify the feature implementation because often you will discover tricky cases that you didn't think of and that may steer the direction of development. The "Lit-based" testsuite makes it easy to run individual tests (run python runlit.py -v [testname] in your build/tests/ directory) so there is no excuse! ;-)
LDC is tested by the LDC Lit-based testsuite and DMD's dmd-testsuite with LDC specific modifications and additions. The dmd-testsuite is put in the tests/d2/ directory. The Lit-based testsuite is found in the subdirectories of tests/, excluding the d2 subfolder.
Merging a new DMD release
Eventually, we will want to write up a checklist of what to consider when merging a new frontend release. Right now, just a few points to consider:
- Check if there were any new command line options added to DMD. if so, also handle them in LDMD.
Updating the dmd-testsuite repository
The dmd-testsuite repository is derived from the upstream DMD repository by the update-dmd-testsuite.sh script in the ldc-scripts repository. Just run it without arguments, and it should update the repository with the latest commits/tags (given that you have Git installed and an SSH key configured for github.com). The changes should apply to the remote repository in a fast-forward fashion, never force a push.
After this is done, when merging a new DMD frontend release, just merge the v2.<xyz> tag into the ldc branch, manually resolving any merge conflicts as necessary (most changes should definitely be upstreamed).
Releasing a new version of LDC
There is a separate page describing the LDC release process: How to release LDC.