Skip to content

Source Code Overview

This document describes the responsibilities and role of each module in the clice source tree, providing readers with a high-level understanding of the overall project structure. For detailed design information on each module, refer to the corresponding topic documents.

Project Vision

clice is a brand-new C++ language server, redesigned from the architecture level to solve long-standing problems in previous C++ language servers. Key features:

  • Compilation Context: clice is the first language server to introduce compilation context as a formal concept. Every step of compilation, indexing, and querying explicitly distinguishes the current compilation context, and users can query and switch between them. See Compilation Context.

  • Multi-process Architecture: A master + worker process model isolates Clang's memory leaks and crashes while enabling priority-aware scheduling and real-time memory monitoring. See Multi-process Architecture.

  • Coroutine-based Async Model: Built on C++20 coroutines and the kotatsu library, replacing traditional callback-style async and making business logic clearer.

  • Real-time Module Compilation: A reference-counted C++20 module compilation DAG with support for real-time cancellation and dependency cascading. See Module Compilation Graph.

Module Overview

src/support/ — Foundation Utility Library

General-purpose utilities and infrastructure shared by all other modules.

  • PathPool: Internalizes file paths as uint32_t identifiers, used as stable file identifiers throughout the system
  • FuzzyMatcher: Token-aware fuzzy matching for code completion and symbol search
  • Markup / Doxygen: Parsing and formatting of documentation comments
  • Logging, filesystem abstractions, string utilities, etc.

src/command/ — Compilation Command Processing

Commands read from the compilation database (CDB) are raw commands generated by the build system and cannot be fed directly to the Clang frontend -- they may contain options meant only for code generation, lack system header search paths, or include parameters irrelevant to a language server. This module classifies, filters, probes toolchains, and deduplicates the raw commands, transforming them into compilation parameters consumable by the language server.

  • CompilationDatabase: Loads compile_commands.json and separates compilation commands into flags that affect semantics (canonical) and flags that only affect user content (patch, such as -I and -D), enabling cross-file command deduplication and sharing
  • Toolchain: Queries system compilers for complete compilation parameters (such as system header search paths), caching results by (driver, file extension, non-user-content flags)
  • SearchConfig: A four-tier model for header search paths (Quoted / Angled / System / After), matching Clang's internal search logic

See Compilation Command Resolution.

src/compile/ — Compilation Abstraction

Wraps the Clang compiler, abstracting Clang APIs into safe, unified compilation interfaces. This layer is purely a compilation abstraction with no server logic.

  • CompilationUnit / CompilationUnitRef: RAII wrappers around the Clang AST context. CompilationUnitRef provides a unified read-only view for accessing source location mappings, preprocessor directives, AST nodes, and more. This is the primary input for src/feature/ and src/semantic/.
  • CompilationParams: Describes the complete configuration for a single compilation, including compilation type (Preamble / Content / Completion / Indexing, etc.), file remapping, PCH/PCM reuse, etc.

src/syntax/ — Lightweight Syntax Processing

Syntax-level processing that does not require a full AST. Runs before compilation to quickly obtain structural information and dependency relationships for files.

  • Lexer: A token-level utility built on Clang's raw lexer. Does not run the preprocessor. Used for directive scanning, include path resolution, etc.
  • DependencyGraph: A global include/module dependency graph supporting forward queries, reverse queries, host source file search, include chain lookup, etc.
  • Dependency scanning: Wraps Clang's DependencyDirectivesScanner to quickly extract include and module dependencies
  • IncludeResolver: Resolves include paths to actual files based on search path configuration

See Dependency Scanning.

src/semantic/ — Semantic Analysis

Semantic analysis capabilities beyond Clang's native APIs. Takes a CompilationUnitRef and extracts higher-level semantic information.

  • SemanticVisitor: An AST traverser that records each symbol's occurrence location and relations (definition, reference, inheritance, call, etc.). This is the primary producer of index data.
  • TemplateResolver: Resolves dependent names through pseudo-instantiation, enabling semantic analysis to see through template contexts. See Template Resolver.
  • SymbolKind / RelationKind: Fine-grained symbol kinds and relation types

src/index/ — Symbol Index

Symbol indexing system with cross-translation-unit query support. Uses a three-tier structure:

  • TUIndex: Index data produced from a single compilation, generated by SemanticVisitor
  • ProjectIndex: The global symbol table. Aggregates symbol information from all indexed files, supporting lookup by symbol hash
  • MergedIndex: Per-file sharded index storage. Merges index data produced from the same file under different compilation contexts

See Symbol Index.

src/feature/ — LSP Feature Implementations

Concrete implementations of LSP features. Each feature takes a CompilationUnitRef and returns the corresponding LSP response data. This layer is purely computational -- it has no involvement with network communication, state management, or process scheduling.

Includes: code completion, hover information, signature help, semantic highlighting, inlay hints, document symbols, document links, folding ranges, formatting, diagnostics, etc.

feature/ only covers single-file, AST-based feature implementations. Cross-file navigation features (go to definition, find references, etc.) are served from index data by the server's service/ layer (FeatureRouter/IndexQuery). Some features involve multi-phase processing -- for example, include path completion in code completion can be resolved at the syntax layer without full compilation.

src/server/ — Server Runtime

The language server's core runtime, responsible for assembling all the layers above into a runnable service.

protocol/ — Protocol definitions. Describes the message formats for communication between the master process and worker processes, as well as between the server and clients. Includes Worker protocol (compilation/query/build requests), LSP extension protocol (compilation context switching, etc.), and the agentic protocol for AI agents.

state/ — Project and document state, plus the invalidation machinery.

  • Workspace: Project-level global state — the compilation database, toolchain, path pool, dependency graph, cache store, and project index. Core invariant: unsaved buffer contents of open files never modify the Workspace -- it only reflects the state on disk
  • Session / SessionStore: The editing state for each open file (buffer contents, document version, in-memory index, PCH reference, etc.), created on didOpen and destroyed on didClose; SessionStore owns the table of open sessions and the buffer-synchronization logic
  • Invalidator: The invalidation engine — folds file events (buffer opens/saves, on-disk changes, compilation-database reloads, worker crashes) into a deduplicated set of invalidation effects
  • FileTracker: Stat-polling discovery of changes that happen outside the editor (a regenerated compile_commands.json, git checkout), feeding events to the Invalidator
  • Config: Loading and merging of clice.toml and LSP initializationOptions

compiler/ — Compilation scheduling and index management.

  • Compiler: The scheduler for compilation lifecycles. Coordinates the ordering of PCH builds, module dependency resolution, and AST compilation, dispatching compilation tasks to worker processes
  • CompileGraph: The DAG scheduler for C++20 module compilation. Uses reference counting for interest tracking, supporting dependency cascade cancellation
  • ContextResolver: Resolves the compile command and includer context a file is compiled under, owning header-context state and synthesized preambles
  • Indexer: Background indexing scheduling — enqueues stale files, dispatches index builds to workers, and merges the resulting shards

service/ — Read-side services consuming compilation and index results.

  • FeatureRouter: Routes feature requests to the compiler (AST-backed features) or the index (cross-file navigation), merging both where needed
  • IndexQuery: The query facade over ProjectIndex, MergedIndex, and the in-memory indexes of open files

transport/ — Protocol endpoints driving the server.

  • MasterServer: The composition root. Owns the Workspace, SessionStore, WorkerPool, and all services above, and executes the Invalidator's effects through its single dispatch entry point
  • LSPClient / AgentClient: Request handlers for the LSP protocol and agentic protocol

worker/ — Worker process management.

  • WorkerPool: Manages worker process lifecycles and scheduling. Stateful workers (StatefulWorker) hold AST and serve query requests. Stateless workers (StatelessWorker) execute one-shot tasks (PCH/PCM builds, completion, indexing, etc.)
  • Process fault tolerance: Workers are automatically restarted on crash. When a stateful worker crashes, its owned documents are automatically reassigned

See Multi-process Architecture.

Inter-module Relationships

The data flow roughly follows this direction:

text
command (compilation command parsing)

compile (drives Clang compilation)

semantic (extracts semantic information) ──→ index (builds indexes)

feature (produces LSP responses)

The server layer assembles all of the above via Workspace / Session / WorkerPool into a runnable service

support and syntax are cross-cutting layers shared by multiple modules.