Contexte et évolution du projet

Après plus de 1 000 commits et quatre mois d’alpha, clice a atteint un jalon décisif : la première version stable, v1.0, est disponible. Depuis le 19 juillet 2026, des nightly builds étaient publiés quotidiennement, permettant aux premiers utilisateurs de signaler des bugs réels. Un système de tests automatisés, exécuté sur de nombreux projets open‑source, a permis de corriger les défauts découverts et de valider chaque fonctionnalité principale. Le résultat est un serveur dont les composants essentiels sont désormais considérés comme stables, réduisant les risques d’instabilité en usage quotidien.

Architecture et choix techniques

clice repose sur LLVM/Clang mais se distingue par une refonte complète de l’architecture. Le code est écrit exclusivement en C++23, avec des coroutines C++20 gérées par une bibliothèque asynchrone maison basée sur libuv et le modèle de « structured concurrency ». Cette approche évite les blocages classiques des serveurs multithreadés et garantit une boucle d’événements unique sur le thread principal, tout en coordonnant plusieurs processus enfants via IPC.

Le projet exploite les modules nommés C++20 et l’importation standard C++23 (import std). Les wrappers de bibliothèques tierces sont générés automatiquement par l’outil clice modularize, rendant le serveur entièrement auto‑hébergé. La réflexion statique, construite sur les concepts et les templates, assure la sérialisation sans code boilerplate pour les formats TOML, JSON, bincode, blob et les arguments en ligne de commande, rappelant les macros Rust.

Sur le plan du design, clice adopte une approche data‑oriented : les virtual functions sont limitées aux seules interfaces requises par Clang, tandis que les API modernes (std::format, std::expected, std::ranges, std::views) remplacent les anciennes constructions C++98/11. Le processus de construction est hermétique grâce à Bazel et à la chaîne unifiée xclang, avec optimisation PGO + LTO pour chaque binaire.

Fonctionnalités clés et performances

Le serveur utilise un pool de processus pour la compilation, à l’instar des navigateurs modernes. Chaque fichier source est compilé dans un processus isolé ; ainsi, un plantage du compilateur n’affecte pas le service global, contrairement à clangd qui repose sur le multithreading. Cette isolation améliore la résilience et facilite la gestion de la mémoire.

clice propose un support complet des modules C++20, incluant la construction paresseuse à la demande et la mise en cache locale des PCH et PCM. Le serveur détecte automatiquement le compilation context d’un fichier non autonome, ce qui permet de travailler sans configuration supplémentaire, à condition de fournir un compile_commands.json. La prise en charge des configurations de build (debug, release, etc.) est intégrée.

En matière de templates, clice implémente un pseudo‑instantiateur DFS qui infère les noms dépendants sans arguments complets, et traite chaque instanciation comme une implémentation d’une interface duck‑typed. Les actions « Go to Implementation », « Find References » et la hiérarchie d’appel fonctionnent ainsi sur l’ensemble des instanciations, offrant une visibilité inédite sur le code générique.

Le serveur détecte plus de 50 toolchains (nvcc, MSYS2, Cygwin, zigcc, …) grâce à un probe d’environnement intégré, éliminant la nécessité d’ajouter manuellement des drapeaux de compilation.

Limites et perspectives

Malgré son avancée, clice dépend fortement de la disponibilité d’un compile_commands.json complet et d’un environnement Clang compatible. L’écosystème des modules C++ reste immature ; certaines bases de code legacy nécessitent encore des ajustements pour profiter pleinement du cache de modules. De plus, la complexité du système de processus isolés impose un coût de démarrage plus élevé que les solutions purement multithreadées. Les futures versions devront améliorer l’intégration avec les systèmes de build non‑Clang et réduire la latence de création des workers.