Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
15f54ea
feat(support): add unified CacheStore blob store
16bit-ykiko Jun 11, 2026
ae0aa9e
feat(command): add canonicalize with argument profiles
16bit-ykiko Jun 11, 2026
cb145d3
feat(server): migrate PCH/PCM/index caches to CacheStore
16bit-ykiko Jun 11, 2026
dd36c1d
fix(support): shield LLVM headers from windows.h min/max macros
16bit-ykiko Jun 11, 2026
5c363b8
fix(support): do not drop mutable-key blobs on rename conflict
16bit-ykiko Jun 11, 2026
1ef1688
fix(server): offload index blob commit fsync to thread pool
16bit-ykiko Jun 11, 2026
0d0bbd3
refactor(server): remove project.index_dir config field
16bit-ykiko Jun 11, 2026
ec80822
test(integration): add formal client process-control API
16bit-ykiko Jun 11, 2026
3307a6b
fix(support): verify blob content on rename collision
16bit-ykiko Jun 11, 2026
87a495f
fix(server): keep persisted index snapshots consistent
16bit-ykiko Jun 11, 2026
ade9017
fix(tests): harden client IO teardown
16bit-ykiko Jun 11, 2026
322dcdd
fix(server): make PCH build registration cancellation-safe
16bit-ykiko Jun 12, 2026
52ed28f
chore(support): document sync-op atomicity and loop-confined TODO
16bit-ykiko Jun 12, 2026
eff8fcf
refactor(support): avoid shell-COM remove_directories on Windows
16bit-ykiko Jun 12, 2026
0b9bfcd
chore(server): drop pre-release legacy cache cleanup
16bit-ykiko Jun 12, 2026
2294252
fix(support): never follow a symlinked root in remove_all
16bit-ykiko Jun 12, 2026
4f6d17d
fix(server): re-validate PCMs until the set is stable
16bit-ykiko Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions docs/clice.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ clang_tidy = false
# exceeds this limit, the least recently used files will be removed.
# The default value is 8. Whatever the number you set, the minimum is 1, the maximum is 512.
max_active_file = 8
# Directory for storing PCH and PCM files.
# Directory for storing on-disk caches (PCH, PCM and index files).
cache_dir = "${workspace}/.clice/cache"
# Directory for storing index files.
index_dir = "${workspace}/.clice/index"
logging_dir = "${workspace}/.clice/logs"
# Compile commands files or directories to search for compile_commands.json files.
compile_commands_paths = ["${workspace}/build"]
Expand Down
9 changes: 1 addition & 8 deletions docs/en/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@ This is the documentation for `clice.toml`.
| ------------------- | -------- | ----------------------------- |
| `project.cache_dir` | `string` | `"${workspace}/.clice/cache"` |

Folder for storing PCH and PCM caches.
<br>

| Name | Type | Default |
| ------------------- | -------- | ----------------------------- |
| `project.index_dir` | `string` | `"${workspace}/.clice/index"` |

Folder for storing index files.
Folder for storing on-disk caches (PCH, PCM and index files).
<br>

## Rule
Expand Down
9 changes: 1 addition & 8 deletions docs/zh/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@
| ------------------- | -------- | ----------------------------- |
| `project.cache_dir` | `string` | `"${workspace}/.clice/cache"` |

用于储存 PCH 和 PCM 缓存的文件夹。
<br>

| 名称 | 类型 | 默认值 |
| ------------------- | -------- | ----------------------------- |
| `project.index_dir` | `string` | `"${workspace}/.clice/index"` |

用于储存索引文件的文件夹。
用于储存磁盘缓存(PCH、PCM 和索引文件)的文件夹。
<br>

## Rule
Expand Down
71 changes: 71 additions & 0 deletions src/command/argument_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,12 @@ using namespace option;
bool is_discarded_option(unsigned id) {
switch(id) {
/// Input file, unknown args, and output — we manage these ourselves.
/// -main-file-name is per-file input identity injected by to_argv()
/// for cc1 commands; it only labels diagnostics/debug info.
case OPT_INPUT:
case OPT_UNKNOWN:
case OPT__DASH_DASH:
case OPT_main_file_name:
case OPT_c:
case OPT_o:
case OPT_dxc_Fc:
Expand Down Expand Up @@ -259,6 +262,74 @@ bool is_codegen_option(unsigned id) {
}
}

bool is_diagnostics_option(unsigned id) {
if(id == OPT_w) {
return true;
}
if(auto opt = option::table().option(id)) {
return opt->matches(OPT_Diag_Group) || opt->matches(OPT_pedantic_Group);
}
return false;
}

std::string canonicalize(llvm::ArrayRef<std::string> args, ArgsProfile profile) {
std::string buf;
if(args.empty()) {
return buf;
}

llvm::raw_string_ostream os(buf);
auto append = [&](std::string_view fragment) {
os << fragment << '\0';
};

/// The driver affects language defaults (clang vs clang++ vs clang-cl).
append(args[0]);

std::vector<std::string> parse_args(args.begin() + 1, args.end());
auto options = kota::option::ParseOptions{.dash_dash_parsing = true,
.visibility = default_visibility(args[0])};
for(auto& result: option::table().parse(parse_args, options)) {
if(!result.has_value()) {
/// Unparseable arguments are kept verbatim: dropping an option
/// we don't understand could merge keys that must differ.
auto index = result.error().index;
if(index < parse_args.size()) {
append(parse_args[index]);
}
continue;
}

auto& arg = *result;

/// Unknown options are kept verbatim, same rationale as parse errors.
if(arg.id == OPT_UNKNOWN) {
if(arg.index < parse_args.size()) {
append(parse_args[arg.index]);
}
continue;
}

bool keep = false;
switch(profile) {
case ArgsProfile::Full: keep = true; break;
case ArgsProfile::Frontend:
keep = !is_discarded_option(arg.id) && !is_codegen_option(arg.id);
break;
case ArgsProfile::Preprocessing:
keep = !is_discarded_option(arg.id) && !is_codegen_option(arg.id) &&
!is_diagnostics_option(arg.id);
break;
}

if(keep) {
option::table().render(arg, append);
}
}

return buf;
}

std::string print_argv(llvm::ArrayRef<const char*> args) {
std::string buf;
llvm::raw_string_ostream os(buf);
Expand Down
34 changes: 34 additions & 0 deletions src/command/argument_parser.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <cstdint>
#include <string>

#include <kota/deco/option.h>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
Expand Down Expand Up @@ -70,6 +73,37 @@ bool is_include_path_option(unsigned id);
/// Check if this is the -Xclang pass-through option.
bool is_xclang_option(unsigned id);

/// Diagnostics-presentation options (-W*, -R*, -pedantic*, -w): they affect
/// which warnings are emitted but never the token stream produced by
/// preprocessing.
bool is_diagnostics_option(unsigned id);

/// Which subset of a compile command matters when deriving a cache key.
enum class ArgsProfile : std::uint8_t {
/// Options that can influence preprocessing: include paths, macros,
/// language dialect and target (predefined macros). Computed
/// subtractively as Frontend minus diagnostics-presentation options,
/// because nearly every language option can define a feature macro —
/// over-inclusion only costs sharing, under-inclusion costs correctness.
Preprocessing,

/// All frontend-semantic options: preprocessing + language + warnings.
/// Excludes codegen-only options and options clice manages itself.
Frontend,

/// Every recognized option, including codegen and inputs.
Full,
};

/// Render the subset of `args` selected by `profile` into a stable string
/// suitable for hashing (fragments are NUL-separated). This is a pure
/// filter: the relative order of kept options is preserved because it is
/// semantically significant (-I/-D ordering). args[0] must be the driver;
/// it is always kept since it affects language defaults. Arguments that
/// fail to parse are kept verbatim — over-keying is safe, under-keying is
/// not.
std::string canonicalize(llvm::ArrayRef<std::string> args, ArgsProfile profile);

/// Get the resource directory for clang builtin headers. Computed once
/// from the current executable path using Driver::GetResourcesPath.
llvm::StringRef resource_dir();
Expand Down
Loading
Loading