Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[clang-tidy] RFC: Add generic check that takes match expression like clang-query #107680

@olologin

Description

@olologin

A wild idea, but maybe someone else will also find it useful, you can close this issue if it doesn't make sense or raises too many concerns.

Can we have clang-tidy check that takes its AST match expressions from clang-query input file?
I can explain why this might be useful:
Clang-tidy has a lot of infrastructure built around it, like plugins for IDE, wrapper-scripts like https://github.com/Ericsson/codechecker which we use at work, and I believe also a lot of other things.
And unfortunately some projects need to have their own weird (but simple) checks, which are useless for upstream clang-tidy. A lot of such checks could be easily expressed as clang-query match expressions, but we dont want to build infrastructure around clang-query. So we have to to build our simple custom checks into clang-tidy/clang-plugin and then build it ourselves. But rebuilding clang-tidy to add simple match expression seems like overkill, especially because you need to build it for different platforms, distribute it, find some way for your developers to keep it updated, and you have to do all this every time some developer decides to improve existing check or add new check.

What if we just develop a new check like clang-query-based which in its configuration takes path to the clang-query file? It seems clang-query parser is already implemented, maybe it is easy to reuse it for this purpose.

Usecase example, in some weird project:

.clang-tidy:

Checks: >
    clang-query-based

CheckOptions:
    clang-query-based.QueryFile: clang-query/custom_query.txt

clang-query/custom_query.txt contents:

match callExpr(
    callee(functionDecl(
        hasAnyName("sort", "nth_element", "partial_sort", "partition"),
        anyOf(
            hasDeclContext(namespaceDecl(hasName("std"))),
            unless(hasParent(namespaceDecl()))
        )
    )),
    isExpansionInFileMatching(".*my_project/dev/.*")
).bind("Please use sort functions from platform-stable library instead of std (std sort functions lead to different results on different platforms)")

match callExpr(
    callee(functionDecl(
        hasAnyName("acos", "asin", "atan", "atan2", "cos", "sin", "tan", "cosh", "sinh", "tanh", "ctan"),
        anyOf(
            hasDeclContext(namespaceDecl(hasName("std"))),
            unless(hasParent(namespaceDecl()))
        )
    )),
    isExpansionInFileMatching(".*my_project/dev/.*")
).bind("Please use math functions from platform-stable library instead of std (std math functions lead to different results on different platforms)")

Alternatively, putting match expressions right into .clang-tidy yaml file (as multiline field) should also work, it is probably even better because caching tools will not have to consider another file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions