Skip to content

nickbabcock/eecs381-lint

Repository files navigation

EECS 381 Lint

Hello intrepid University of Michigan student!

You're taking EECS 381 - Object-Oriented and Advanced Programming and heard there are style guidelines for C and C++. Most of the guidelines make sense and are easy to keep in the back of your mind, but even I slip up and forget occasionally. This repo is here to help.

By taking advantage of the clang compiler's deep knowledge of C/C++ files we can create robust patterns to match on code that isn't as error prone as regular expressions and tokenizing C code yourself. This repo adds checks to clang-tidy to run against your code.

There are only a couple lints implemented at the moment, so please check the style guide by hand as well as by using this tool.

If you take away one thing from this repo -- even if you don't use this repo -- use clang-tidy!

Getting Started

Writing plugins for clang-tidy, unfortunately means you need to compile the whole clang toolchain, which requires a relatively beefy machine (8GB RAM and 5GB disk free). To make compilation reasonable, we're using the gold linker (which is in your development tools already if you are on a recent version of Ubuntu) and doing a release build so that all the debug symbols aren't included (which will take up 50GB+ of space)

git clone --recursive https://github.com/nickbabcock/eecs381-lint
cd eecs381-lint

# LLVM is large, so to keep all of the subprojects manageable, we recreate the
# mono-repo by linking clang and clang-tidy appropriately.
ln -s clang-tools-extra clang/tools/extra
ln -s clang llvm/tools/.
mkdir -p eecs381-lint/build
cd eecs381-lint/build
cmake -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
               -DLLVM_PARALLEL_LINK_JOBS=1 \
               -DLLVM_USE_LINKER=gold \
               -DCMAKE_BUILD_TYPE=Release \
               ../llvm

ninja check-clang-tools
# And now we wait awhile.
# Our clang-tidy executable is in bin/clang-tidy

(For contributors): we use git-subrepo to manage our modifications to the clang-tools-extra repo.

History

The first implementation, written in 2013, was a plugin written for vera++, which parses C/C++ code and hands tokens to Tcl scripts written by you. As a first implementation this is fine, but I believe one is limited in the confidence of the solution as they aren't handed a deep and rich AST that can be interrogated. It's a step above regular expressions, but still far from ideal. Tcl is also an odd choice -- not that it is the wrong choice, but in all my time this has been the only codebase that I've written Tcl and it didn't leave a great impression.

Maybe the best reason for migrating away from vera is that it's simply not as well supported as clang-tidy. The last commit for vera was in the first half of 2016. Clang tidy receives updates weekly if not daily. There is a difference between mature software that is stable and doesn't receive updates and projects where the maintainers have moved on. For instance, vera doesn't understand much of C++11 syntax, and thus will be confused when parsing modern C++ files.

Checks

Typedef end in _t

struct Point {
    int x;
    int y;
};

typedef struct Point Point_t;

typedef struct Point Pointed;

typedef struct Thing {
   int cheese;
} Thing;

typedef struct Book {
   int author;
} Book_t;

Results in the following errors:

misc-eecs-typedef-t.cpp:10:22: warning: typedefs must end in `_t` ('Pointed') [misc-eecs-typedef-t]
typedef struct Point Pointed;
                     ^
misc-eecs-typedef-t.cpp:15:3: warning: typedefs must end in `_t` ('Thing') [misc-eecs-typedef-t]
} Thing;
  ^

Source code / Test file

Do not define TRUE or FALSE

#define TRUE 1

#define TODO 100

Results in the following error:

misc-eecs-bool-define.cpp:1:9: warning: Do not define TRUE or FALSE macros: 'TRUE' [misc-eecs-bool-define]
#define TRUE 1
        ^

Source code / Test file

Enums must end in "_e"

enum X {
  A, B, C
};

enum X_e {
  AA, BB, CC
};

Results in the following error:

misc-eecs-enum-suffix.cpp:1:6: warning: enum declarations must end in `_e` ('X') [misc-eecs-enum-suffix]
enum X {
     ^

Source code / Test file

Enum vales must be uppercase

enum Fruit_e {
    APPLES,
    bANANAS
};

Results in the following error:

misc-eecs-enum-value-caps.cpp:5:5: warning: enum values must be uppercased ('bANANAS') [misc-eecs-enum-value-caps]
    bANANAS
    ^

Source code / Test file

About

Additional style checks for C/C++ for clang-tidy

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published