Skip to content

Commit fcf031f

Browse files
committed
Initial work on generating the toolchains.
Also, for now hardcode the flags to parse in C mode for wasm32
1 parent f5d304c commit fcf031f

File tree

7 files changed

+563
-439
lines changed

7 files changed

+563
-439
lines changed

package-lock.json

Lines changed: 334 additions & 297 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"url": "https://github.com/robertoraggi/cplusplus/issues"
2525
},
2626
"devDependencies": {
27+
"@types/node": "^24.0.13",
2728
"jsonc-cli": "^1.0.2",
2829
"zx": "^8.6.1"
2930
},

scripts/update-predefined-macros.mjs

Lines changed: 0 additions & 60 deletions
This file was deleted.

scripts/update-toolchain.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { execFile } from "node:child_process";
2+
3+
const machines = ["aarch64", "x86_64", "wasm32"] as const;
4+
const oses = ["linux", "macosx", "windows", "wasi"] as const;
5+
const compilers = ["c23", "c++26"];
6+
7+
type Machine = (typeof machines)[number];
8+
type OS = (typeof oses)[number];
9+
type Compiler = (typeof compilers)[number];
10+
type Config = [machine: Machine, os: OS, compiler: Compiler];
11+
12+
const configs: Config[] = [
13+
["aarch64", "linux", "c++26"],
14+
["aarch64", "linux", "c23"],
15+
["aarch64", "macosx", "c++26"],
16+
["aarch64", "macosx", "c23"],
17+
["aarch64", "windows", "c++26"],
18+
["aarch64", "windows", "c23"],
19+
["wasm32", "wasi", "c++26"],
20+
["wasm32", "wasi", "c23"],
21+
["x86_64", "linux", "c++26"],
22+
["x86_64", "linux", "c23"],
23+
["x86_64", "macosx", "c++26"],
24+
["x86_64", "macosx", "c23"],
25+
["x86_64", "windows", "c++26"],
26+
["x86_64", "windows", "c23"],
27+
];
28+
29+
function configMatches({
30+
config,
31+
machine,
32+
os,
33+
compiler,
34+
}: {
35+
config: Config;
36+
machine?: Machine;
37+
os?: OS;
38+
compiler?: Compiler;
39+
}): boolean {
40+
const [configMachine, configOS, configCompiler] = config;
41+
return (
42+
(machine ? configMachine === machine : true) &&
43+
(os ? configOS === os : true) &&
44+
(compiler ? configCompiler === compiler : true)
45+
);
46+
}
47+
48+
async function getPredefinedMacros({
49+
config,
50+
}: {
51+
config: Config;
52+
}): Promise<Set<string>> {
53+
const [machine, os, compiler] = config;
54+
55+
const lang = compiler.startsWith("c++") ? "c++" : "c";
56+
const target = `${machine}-${os}`;
57+
58+
return new Promise((resolve, reject) => {
59+
execFile(
60+
"clang",
61+
[
62+
`--target=${target}`,
63+
"-E",
64+
"-dM",
65+
`-x${lang}`,
66+
`-std=${compiler}`,
67+
"/dev/null",
68+
],
69+
(err, stdout) => {
70+
if (err) {
71+
reject(err);
72+
return;
73+
}
74+
75+
const predefinedMacros = stdout
76+
.split("\n")
77+
.map((line) => line.trim())
78+
.filter(Boolean);
79+
80+
resolve(new Set(predefinedMacros));
81+
}
82+
);
83+
});
84+
}
85+
86+
async function main() {
87+
const predefinedMacrosByConfig: Record<string, Set<string>> = {};
88+
for (const config of configs) {
89+
const predefinedMacros = await getPredefinedMacros({ config });
90+
predefinedMacrosByConfig[config.join("-")] = predefinedMacros;
91+
console.log(
92+
`Config: ${config.join("-")} has ${predefinedMacros.size} predefined macros.`
93+
);
94+
}
95+
96+
machines.forEach((machine) => {
97+
const machineConfigs = configs.filter((config) =>
98+
configMatches({ config, machine })
99+
);
100+
const predefinedMacrosForMachine = machineConfigs.map((config) => {
101+
return predefinedMacrosByConfig[config.join("-")];
102+
});
103+
return intersection(...predefinedMacrosForMachine);
104+
});
105+
}
106+
107+
function intersection<T>(...sets: Set<T>[]): Set<T> {
108+
if (sets.length === 0) return new Set();
109+
return sets.reduce((acc, set) => {
110+
const intersection = new Set<T>();
111+
for (const item of set) {
112+
if (acc.has(item)) {
113+
intersection.add(item);
114+
}
115+
}
116+
return intersection;
117+
}, sets[0]);
118+
}
119+
120+
await main();

src/frontend/cxx/frontend.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,13 @@ auto readAll(const std::string& fileName) -> std::optional<std::string> {
117117
}
118118

119119
void dumpTokens(const CLI& cli, TranslationUnit& unit, std::ostream& output) {
120-
const auto lang =
121-
cli.getSingle("-x") == "c" ? LanguageKind::kC : LanguageKind::kCXX;
120+
auto lang = LanguageKind::kCXX;
121+
122+
if (auto x = cli.getSingle("x")) {
123+
if (x == "c") lang = LanguageKind::kC;
124+
} else if (unit.fileName().ends_with(".c")) {
125+
lang = LanguageKind::kC;
126+
}
122127

123128
std::string flags;
124129

@@ -158,7 +163,7 @@ auto runOnFile(const CLI& cli, const std::string& fileName) -> bool {
158163

159164
const auto lang = cli.getSingle("-x");
160165

161-
if (lang == "c") {
166+
if (lang == "c" || (!lang.has_value() && fileName.ends_with(".c"))) {
162167
// set the language to C
163168
preprocessor->setLanguage(LanguageKind::kC);
164169
}

0 commit comments

Comments
 (0)