|
| 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