Skip to content

Commit 10bdc89

Browse files
committed
feat(P2): add toolchain ProviderCapabilities dispatch layer
Centralise the scattered is_clang/is_gcc/targetTriple.find("msvc") checks into a single capabilities_for(tc) query in src/toolchain/provider.cppm. The new ProviderCapabilities struct exposes has_import_std, has_scan_deps, has_modules, stdlib_id ("libstdc++" / "libc++" / "msvc-stl"), and archive_format ("ar" / "llvm-ar" / "lib.exe") — one place to update when a new compiler variant is added. No existing call-sites are changed in this commit; provider.cppm documents the provider concept and is ready for callers to migrate to incrementally.
1 parent 1969d19 commit 10bdc89

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

src/toolchain/provider.cppm

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// mcpp.toolchain.provider — provider capabilities dispatch.
2+
//
3+
// Documents the "provider concept": each toolchain variant (GCC/libstdc++,
4+
// Clang/libc++, Clang/MSVC-STL) has a distinct set of capabilities.
5+
// Previously these decisions were scattered as ad-hoc is_clang(tc) /
6+
// is_gcc(tc) / targetTriple.find("msvc") checks. This module centralises
7+
// them into a single query point.
8+
//
9+
// Usage:
10+
// auto caps = mcpp::toolchain::capabilities_for(tc);
11+
// if (caps.has_import_std) { ... }
12+
13+
export module mcpp.toolchain.provider;
14+
15+
import std;
16+
import mcpp.toolchain.model;
17+
18+
export namespace mcpp::toolchain {
19+
20+
// ─── ProviderCapabilities ────────────────────────────────────────────────────
21+
//
22+
// Describes what a particular toolchain instance can do. All fields have
23+
// safe defaults (false / empty) so callers that only care about one flag
24+
// do not need to guard the rest.
25+
26+
struct ProviderCapabilities {
27+
// True when the toolchain ships a prebuilt `std` module source
28+
// (bits/std.cc for GCC, std.cppm / std.ixx for Clang variants) and
29+
// Toolchain::stdModuleSource has been populated by enrich_toolchain().
30+
bool has_import_std = false;
31+
32+
// True when clang-scan-deps (or an equivalent dep-scanner) is available
33+
// alongside the compiler binary. Currently only Clang provides this.
34+
bool has_scan_deps = false;
35+
36+
// True when the compiler supports C++ named modules at all.
37+
// All three supported compilers do; kept for future use when we add
38+
// compilers that don't (e.g. old MSVC versions, ICC).
39+
bool has_modules = true;
40+
41+
// Canonical stdlib identifier:
42+
// "libstdc++" — GCC, or Clang targeting a non-MSVC triple on Linux/macOS
43+
// "libc++" — Clang with libc++ (xim:llvm toolchain, or Apple Clang)
44+
// "msvc-stl" — Clang targeting x86_64-pc-windows-msvc
45+
// "" — Unknown / not yet detected
46+
std::string stdlib_id;
47+
48+
// Archive tool name used for static libraries:
49+
// "ar" — GCC / system binutils
50+
// "llvm-ar" — Clang (llvm-ar is preferred; falls back to system ar)
51+
// "lib.exe" — MSVC (future)
52+
// "" — Unknown
53+
std::string archive_format;
54+
};
55+
56+
// Determine provider capabilities from an already-detected toolchain.
57+
// All fields are derived from tc.compiler + tc.targetTriple + tc.hasImportStd
58+
// so the result is deterministic and has no side-effects.
59+
ProviderCapabilities capabilities_for(const Toolchain& tc);
60+
61+
} // namespace mcpp::toolchain
62+
63+
// ─── Implementation ──────────────────────────────────────────────────────────
64+
65+
namespace mcpp::toolchain {
66+
67+
ProviderCapabilities capabilities_for(const Toolchain& tc) {
68+
ProviderCapabilities caps;
69+
70+
caps.has_import_std = tc.hasImportStd;
71+
caps.has_modules = true; // all supported compilers handle modules
72+
73+
switch (tc.compiler) {
74+
case CompilerId::GCC: {
75+
caps.has_scan_deps = false; // GCC has no clang-scan-deps equivalent
76+
caps.stdlib_id = "libstdc++";
77+
caps.archive_format = "ar";
78+
break;
79+
}
80+
81+
case CompilerId::Clang: {
82+
// Clang targeting MSVC uses MSVC STL, not libc++.
83+
// We detect this the same way clang.cppm's enrich_toolchain does:
84+
// by checking the target triple for "msvc".
85+
bool msvc_target = tc.targetTriple.find("msvc") != std::string::npos;
86+
87+
caps.has_scan_deps = true; // clang-scan-deps lives beside clang++
88+
caps.stdlib_id = msvc_target ? "msvc-stl" : "libc++";
89+
caps.archive_format = "llvm-ar";
90+
break;
91+
}
92+
93+
case CompilerId::MSVC: {
94+
// Pure MSVC (cl.exe) — not yet fully supported, but stubs are here
95+
// so callers can branch on it without another unknown-compiler guard.
96+
caps.has_scan_deps = false;
97+
caps.stdlib_id = "msvc-stl";
98+
caps.archive_format = "lib.exe";
99+
break;
100+
}
101+
102+
case CompilerId::Unknown:
103+
default:
104+
// Leave all caps at their safe defaults (false / "").
105+
break;
106+
}
107+
108+
return caps;
109+
}
110+
111+
} // namespace mcpp::toolchain

0 commit comments

Comments
 (0)