Outils pour utilisateurs

Outils du site


prog:clang-tidy

Ceci est une ancienne révision du document !


clang-tidy détecte les parties du code qui sont soit bancals, soit pourrait être écrite d'une meilleure façon.

Ne pas utiliser :

  • readability-static-accessed-through-instance dans le cas d'un projet Qt. Dans la déclaration des classes, les champs public : … public slot : seront considérés comme des doublons car slot est enlevé lors du preprocessing.

CMake

S'intègre parfaitement avec CMake.

Il faut commencer par activer l'option set(CMAKE_EXPORT_COMPILE_COMMANDS ON).

Puis lancer la génération des Makefile avec CC="clang" CXX="clang++" cmake -S . -B build pour générer également le fichier compile_commands.json. L'utilisation du compilateur clang n'est pas obligatoire. Elle est simplement là pour vérifier que le code compile bien avec clang.

L'analyse se lance avec run-clang-tidy.

Options

  • Configuration des règles

Le fichier de config peut se générer via clang-tidy --dump-config > .clang-tidy. Il est conseillé de générer ce fichier à chaque changement de version de clang, certaines options pouvant être supprimées ou renommées.

Exemple du début du fichier .clang-tidy:

.clang-tidy
---
Checks:          '*,-llvm-header-guard,-modernize-use-trailing-return-type,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-fuchsia-default-arguments-calls'
WarningsAsErrors: '*'
HeaderFilterRegex: ''
...

Clang-Tidy, part 1: Modernize your source code using C++11/C++14 Archive du 16/03/2017 le 13/02/2020

  • Analyse uniquement certains dossiers

Il est aussi possible de filtrer certains dossiers :

run-clang-tidy-12 '^((?!/path1/|/path2/).)*$'
  • Spécifier la localisation de clang-tidy

Peut être utile si on souhaite utiliser clang-tidy pour Android qui est différent de celui du système mais run-clang-tidy n'est pas fourni dans le SDK Android.

/usr/lib/llvm-14/bin/run-clang-tidy -clang-tidy-binary .../Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang-tidy
  • Exclure certains fichiers

Il faut modifier le fichier compile_commands.json avec une commande perl qui autorise les regex multilignes.

perl -0777 -i.original -pe 's/,\n\{\n.*\n.*_RCS_FILES\.cpp",\n.*_RCS_FILES\.cpp"\n\}//g' compile_commands.json
perl -0777 -i.original -pe 's/\{\n.*\n.*_RCS_FILES\.cpp",\n.*_RCS_FILES\.cpp"\n\},\n//g' compile_commands.json

Gestion les erreurs

  • Ignorer la vérification sur des lignes de code spécifiques
badcode;  // NOLINT
 
// NOLINTNEXTLINE
badcode;
 
badcode;  // NOLINT(cert-err-58-cpp)
 
// NOLINTBEGIN(google*)
Foo(bool param);
// NOLINTEND(google*)

Détail des règles

readability-identifier-naming

Priorité de la convention de nommage:

Voir directement le code source avec les méthodes findStyleKind, findStyleKindForField et findStyleKindForVar.

Ci-dessous, defined(Xxxx) signifie que XxxxCase, XxxxPrefix, XxxxSuffix, XxxxIgnoredRegex ou XxxxHungarianPrefix est dans les règles.

si (variable Objective-C && defined(ObjcIvar))
  => ObjcIvar

si (typedef && defined(Typedef))
  => Typedef

si (using && defined(TypeAlias))
  => TypeAlias

si (namespace)
  si (namespace est inline) && defined(InlineNamespace)
    =>InlineNamespace

  si defined(Namespace)
    =>Namespace

si (enum && defined(Enum))
  => Enum

si (valeur d'un enum)
  si (enum class && defined(ScopedEnumConstant))
    => ScopedEnumConstant
  si (defined(EnumConstant))
    => EnumConstant
  si (defined(Constant))
    => Constant
  => Ignore

si (union ou struct ou class)
  si (abstract (au moins une méthode virtuelle pure) && defined(AbstractClass))
    => AbstractClass
  si (struct && defined(Struct))
    => Struct
  si (struct && defined(Class))
    => Class
  si (class && defined(Class))
    => Class
  si (class && defined(Struct))
    => Struct
  si (union && defined(Union))
    => Union
  si (enum && defined(Enum))
    => Enum
  => Ignore

si (membre d'une classe)
  si (option CheckAnonFieldInParent && struct/union parent est anonyme)
    Appliquer les règles ci-dessous en considérant le private/protected/public du parent.
  si (const)
    si (defined(ConstantMember))
      => ConstantMember
    si (defined(Constant))
      => Constant
  si (private && defined(PrivateMember))
    => PrivateMember
  si (protected && defined(ProtectedMember))
    => ProtectedMember
  si (public && defined(PublicMember))
    => PublicMember
  si (defined(Member))
    => Member
  => Ignore

si (paramètre d'une fonction)
  si (constexpr && defined(ConstexprVariable)) // C'est possible ?
    => ConstexprVariable
  si (const)
    si (pointer && defined(ConstantPointerParameter))
      => ConstantPointerParameter
    si (defined(ConstantParameter))
      => ConstantParameter
    si (defined(Constant))
      => Constant
  si (variadic && defined(ParameterPack))
    => ParameterPack
  si (pointer && defined(PointerParameter))
    => PointerParameter
  si (defined(Parameter))
    => Parameter
  => Ignore

si (variable)
  si (constexpr && defined(ConstexprVariable))
    => ConstexprVariable
  si (const)
    si (static && defined(ClassConstant))
      => ClassConstant
    si (global && pointer && defined(GlobalConstantPointer))
      => GlobalConstantPointer
    si (global && defined(GlobalConstant))
      => GlobalConstant
    si (local && static && defined(StaticConstant))
      => StaticConstant
    si (local && pointer && defined(LocalConstantPointer))
      => LocalConstantPointer
    si (local && defined(LocalConstant))
      => LocalConstant
    si (defined(Constant))
      => Constant
    
  si (static && defined(ClassMember))
    => ClassMember
  si (global && pointer && defined(GlobalPointer))
    => GlobalPointer
  si (global && defined(GlobalVariable))
    => GlobalVariable
  si (local && static && defined(StaticVariable))
    => StaticVariable
  si (local && pointer && defined(LocalPointer))
    => LocalPointer
  si (local && defined(LocalVariable))
    => LocalVariable
  si (defined(Variable))
    => Variable
  => Ignore

si (methode)
  si (override)
    => Ignore
  si (constexpr && defined(ConstexprMethod))
    => ConstexprMethod
  si (constexpr && defined(ConstexprFunction))
    => ConstexprFunction
  si (static && defined(ClassMethod))
    => ClassMethod
  si (virtual && defined(VirtualMethod))
    => VirtualMethod
  si (private && defined(PrivateMethod))
    => PrivateMethod
  si (protected && defined(ProtectedMethod))
    => ProtectedMethod
  si (public && defined(PublicMethod))
    => PublicMethod
  si (defined(Method))
    => Method
  si (defined(Function))
    => Function
  => Ignore

si (fonction)
  si (constexpr && defined(ConstexprFunction))
    => ConstexprFunction
  si (global && defined(GlobalFunction))
    => GlobalFunction
  si (defined(Function))
    => Function

si (typename in template)
  si (defined(TypeTemplateParameter))
    => TypeTemplateParameter
  si (defined(TemplateParameter))
    => TemplateParameter
  => Ignore

si (value in template)
  si (defined(ValueTemplateParameter))
    => ValueTemplateParameter
  si (defined(TemplateParameter))
    => TemplateParameter
  => Ignore

si (template <typename> class / typename)
  si (defined(TemplateTemplateParameter))
    => TemplateTemplateParameter
  si (defined(TemplateParameter))
    => TemplateParameter
  => Ignore

si (concept && defined(Concept))
  => Concept

=> Ignore

Extensions

Cache

kokulshan/clang-tidy-cache

Site web

  • Installation

Il faut avoir installé go.

make
  • Exécution
CLANG_TIDY_CACHE_BINARY=/usr/bin/clang-tidy-17 CLANG_TIDY_CACHE_DIR=~/.cache/clang-tidy-cache run-clang-tidy-17 -clang-tidy-binary /usr/local/bin/clang-tidy-cache

matus-chochlik/ctcache

Site web

  • Installation

Il suffit de copier les scripts python clang-tidy et clang-tidy-cache dans /usr/local/bin.

  • Execution
CTCACHE_CLANG_TIDY=/usr/bin/clang-tidy CTCACHE_DIR=~/.cache/clang-tidy-cache run-clang-tidy -clang-tidy-binary /usr/local/bin/clang-tidy
prog/clang-tidy.1733383120.txt.gz · Dernière modification : 2024/12/05 08:18 de root