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