Skip to content

Commit b2ebf63

Browse files
committed
Swift: split generated C++ code into .h and .cpp
1 parent 3248f7b commit b2ebf63

File tree

14 files changed

+114
-59
lines changed

14 files changed

+114
-59
lines changed

swift/codegen/generators/cppgen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@ def generate(opts, renderer):
7878
assert opts.cpp_output
7979
processor = Processor({cls.name: cls for cls in schema.load(opts.schema).classes})
8080
out = opts.cpp_output
81-
renderer.render(cpp.ClassList(processor.get_classes(), opts.schema), out / f"TrapClasses.h")
81+
renderer.render(cpp.ClassList(processor.get_classes(), opts.schema), out / "TrapClasses")

swift/codegen/generators/trapgen.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ def generate(opts, renderer):
8080
for d in e.rhs:
8181
tag_graph.setdefault(d.type, set()).add(e.lhs)
8282

83-
renderer.render(cpp.TrapList(traps, opts.dbscheme),
84-
out / f"TrapEntries.h")
83+
renderer.render(cpp.TrapList(traps, opts.dbscheme), out / "TrapEntries")
8584

8685
tags = []
8786
for index, tag in enumerate(toposort_flatten(tag_graph)):
@@ -91,4 +90,4 @@ def generate(opts, renderer):
9190
index=index,
9291
id=tag,
9392
))
94-
renderer.render(cpp.TagList(tags, opts.dbscheme), out / f"TrapTags.h")
93+
renderer.render(cpp.TagList(tags, opts.dbscheme), out / "TrapTags")

swift/codegen/lib/cpp.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,15 @@ def has_bases(self):
9999
@dataclass
100100
class TrapList:
101101
template: ClassVar = 'trap_traps'
102-
102+
extensions = ["h", "cpp"]
103103
traps: List[Trap]
104104
source: str
105105

106106

107107
@dataclass
108108
class TagList:
109109
template: ClassVar = 'trap_tags'
110+
extensions = ["h"]
110111

111112
tags: List[Tag]
112113
source: str
@@ -143,6 +144,7 @@ def single_fields(self):
143144
@dataclass
144145
class ClassList:
145146
template: ClassVar = "cpp_classes"
147+
extensions: ClassVar = ["h", "cpp"]
146148

147149
classes: List[Class]
148150
source: str

swift/codegen/lib/render.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,23 @@ def render(self, data, output: pathlib.Path):
2828
2929
`data` must have a `template` attribute denoting which template to use from the template directory.
3030
31-
If the file is unchanged, then no write is performed (and `done_something` remains unchanged)
32-
33-
If `guard_base` is provided, it must be a path at the root of `output` and a header guard will be injected in
34-
the template based off of the relative path of `output` in `guard_base`
31+
Optionally, `data` can also have an `extensions` attribute denoting list of file extensions: they will all be
32+
appended to the template name with an underscore and be generated in turn.
3533
"""
3634
mnemonic = type(data).__name__
3735
output.parent.mkdir(parents=True, exist_ok=True)
38-
data = self._r.render_name(data.template, data, generator=self._generator)
39-
with open(output, "w") as out:
40-
out.write(data)
41-
log.debug(f"generated {mnemonic} {output.name}")
42-
self.written.add(output)
36+
extensions = getattr(data, "extensions", [None])
37+
for ext in extensions:
38+
output_filename = output
39+
template = data.template
40+
if ext:
41+
output_filename = output_filename.with_suffix(f".{ext}")
42+
template += f"_{ext}"
43+
contents = self._r.render_name(template, data, generator=self._generator)
44+
with open(output_filename, "w") as out:
45+
out.write(contents)
46+
log.debug(f"{mnemonic}: generated {output.name}")
47+
self.written.add(output_filename)
4348

4449
def cleanup(self, existing):
4550
""" Remove files in `existing` for which no `render` has been called """
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// generated by {{generator}} from {{source}}
2+
// clang-format off
3+
#include "./TrapClasses.h"
4+
5+
namespace codeql {
6+
{{#classes}}
7+
8+
void {{name}}::emit({{^final}}TrapLabel<{{name}}Tag> id, {{/final}}std::ostream& out) const {
9+
{{#trap_name}}
10+
out << {{.}}Trap{id{{#single_fields}}, {{field_name}}{{/single_fields}}} << '\n';
11+
{{/trap_name}}
12+
{{#bases}}
13+
{{ref.name}}::emit(id, out);
14+
{{/bases}}
15+
{{#fields}}
16+
{{#is_predicate}}
17+
if ({{field_name}}) out << {{trap_name}}Trap{id} << '\n';
18+
{{/is_predicate}}
19+
{{#is_optional}}
20+
{{^is_repeated}}
21+
if ({{field_name}}) out << {{trap_name}}Trap{id, *{{field_name}}} << '\n';
22+
{{/is_repeated}}
23+
{{/is_optional}}
24+
{{#is_repeated}}
25+
for (auto i = 0u; i < {{field_name}}.size(); ++i) {
26+
{{^is_optional}}
27+
out << {{trap_name}}Trap{id, i, {{field_name}}[i]};
28+
{{/is_optional}}
29+
{{#is_optional}}
30+
if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]};
31+
{{/is_optional}}
32+
}
33+
{{/is_repeated}}
34+
{{/fields}}
35+
}
36+
{{/classes}}
37+
}

swift/codegen/templates/cpp_classes.mustache renamed to swift/codegen/templates/cpp_classes_h.mustache

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,7 @@ struct {{name}}{{#has_bases}} : {{#bases}}{{^first}}, {{/first}}{{ref.name}}{{/b
3131
{{/final}}
3232

3333
protected:
34-
void emit({{^final}}TrapLabel<{{name}}Tag> id, {{/final}}std::ostream& out) const {
35-
{{#trap_name}}
36-
out << {{.}}Trap{id{{#single_fields}}, {{field_name}}{{/single_fields}}} << '\n';
37-
{{/trap_name}}
38-
{{#bases}}
39-
{{ref.name}}::emit(id, out);
40-
{{/bases}}
41-
{{#fields}}
42-
{{#is_predicate}}
43-
if ({{field_name}}) out << {{trap_name}}Trap{id} << '\n';
44-
{{/is_predicate}}
45-
{{#is_optional}}
46-
{{^is_repeated}}
47-
if ({{field_name}}) out << {{trap_name}}Trap{id, *{{field_name}}} << '\n';
48-
{{/is_repeated}}
49-
{{/is_optional}}
50-
{{#is_repeated}}
51-
for (auto i = 0u; i < {{field_name}}.size(); ++i) {
52-
{{^is_optional}}
53-
out << {{trap_name}}Trap{id, i, {{field_name}}[i]};
54-
{{/is_optional}}
55-
{{#is_optional}}
56-
if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]};
57-
{{/is_optional}}
58-
}
59-
{{/is_repeated}}
60-
{{/fields}}
61-
}
34+
void emit({{^final}}TrapLabel<{{name}}Tag> id, {{/final}}std::ostream& out) const;
6235
};
6336

6437
template <>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// generated by {{generator}} from {{source}}
2+
// clang-format off
3+
#include "./TrapEntries.h"
4+
5+
namespace codeql {
6+
{{#traps}}
7+
8+
// {{table_name}}
9+
std::ostream &operator<<(std::ostream &out, const {{name}}Trap &e) {
10+
out << "{{table_name}}("{{#fields}}{{^first}} << ", "{{/first}}
11+
<< {{#get_streamer}}e.{{field_name}}{{/get_streamer}}{{/fields}} << ")";
12+
return out;
13+
}
14+
{{/traps}}
15+
}

swift/codegen/templates/trap_traps.mustache renamed to swift/codegen/templates/trap_traps_h.mustache

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,12 @@ namespace codeql {
1414

1515
// {{table_name}}
1616
struct {{name}}Trap {
17-
static constexpr bool is_binding = {{#id}}true{{/id}}{{^id}}false{{/id}};
18-
{{#id}}
19-
{{type}} getBoundLabel() const { return {{field_name}}; }
20-
{{/id}}
21-
2217
{{#fields}}
2318
{{type}} {{field_name}}{};
2419
{{/fields}}
2520
};
2621

27-
inline std::ostream &operator<<(std::ostream &out, const {{name}}Trap &e) {
28-
out << "{{table_name}}("{{#fields}}{{^first}} << ", "{{/first}}
29-
<< {{#get_streamer}}e.{{field_name}}{{/get_streamer}}{{/fields}} << ")";
30-
return out;
31-
}
22+
std::ostream &operator<<(std::ostream &out, const {{name}}Trap &e);
3223
{{#id}}
3324

3425
namespace detail {

swift/codegen/test/test_cppgen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ def generate(opts, renderer, input):
1414
def ret(classes):
1515
input.classes = classes
1616
generated = run_generation(cppgen.generate, opts, renderer)
17-
assert set(generated) == {output_dir / "TrapClasses.h"}
18-
generated = generated[output_dir / "TrapClasses.h"]
17+
assert set(generated) == {output_dir / "TrapClasses"}
18+
generated = generated[output_dir / "TrapClasses"]
1919
assert isinstance(generated, cpp.ClassList)
2020
return generated.classes
2121

0 commit comments

Comments
 (0)