Skip to content

Commit b507e2a

Browse files
committed
Fixed some more DLL bugs.
1 parent 1a0ee4a commit b507e2a

File tree

11 files changed

+161
-90
lines changed

11 files changed

+161
-90
lines changed

build_rules/xt_inst_gen.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494

9595
<ItemGroup>
9696
<Xt_Comp_Set Include="@(Xt_Headers)">
97-
<Command>$(Xt_Command) comp "%(FullPath)" "%(Xt_Headers.InstFilePath)" "$(Xt_PreprocessorDefinitions)" "$(Xt_AdditionalIncludeDirectories)" "$(ProjectGuid)"</Command>
97+
<Command>$(Xt_Command) comp "%(FullPath)" "%(Xt_Headers.InstFilePath)" "$(Xt_PreprocessorDefinitions)" "$(Xt_AdditionalIncludeDirectories)"</Command>
9898
</Xt_Comp_Set>
9999
</ItemGroup>
100100

src/xt_inst_gen/xt_comp.cpp

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ int find_exported_templates(
7171
std::string file_path,
7272
const std::vector<std::string_view> & pp_defs,
7373
const std::vector<std::string_view> & include_dirs,
74-
const std::function<void(const std::string &)> & symbol_cb)
74+
const std::function<void(const std::string &, std::string_view)> & symbol_cb)
7575
{
7676
//bug?: this doesn't work with backslashes !
7777
std::replace(file_path.begin(), file_path.end(), '\\', '/');
@@ -153,10 +153,9 @@ int find_exported_templates(
153153
#endif
154154

155155
fmt::print("function template: {}\n", full_name);
156-
if (cppast::has_attribute(e, "dllexport")) // todo
157-
fmt::print("is exported\n");
158156

159-
symbol_cb(full_name);
157+
char * flags = cppast::has_attribute(e, "dllexport") ? "fd" : "f";
158+
symbol_cb(full_name, flags);
160159
}
161160

162161
if (e.kind() == cppast::cpp_class_template::kind() &&
@@ -168,10 +167,9 @@ int find_exported_templates(
168167
std::string full_name = get_fully_qualified_name_without_templates(class_);
169168

170169
fmt::print("class template: {}\n", full_name);
171-
if (cppast::has_attribute(e, "dllexport")) // todo
172-
fmt::print("is exported\n");
173170

174-
symbol_cb(full_name);
171+
char * flags = cppast::has_attribute(e, "dllexport") ? "cd" : "c";
172+
symbol_cb(full_name, flags);
175173
}
176174

177175
return true;
@@ -183,12 +181,12 @@ int find_exported_templates(
183181

184182
int print_comp_usage() {
185183
fmt::print("usage: {} comp xt_file_path xt_inst_file_path "
186-
"preprocessor_definitions include_directories impl_project_name\n", tool_name);
184+
"preprocessor_definitions include_directories\n", tool_name);
187185
return 1;
188186
}
189187

190188
int do_comp(int argc, const char *argv[]) {
191-
if (argc < 6) {
189+
if (argc < 5) {
192190
return print_comp_usage();
193191
}
194192

@@ -204,8 +202,6 @@ int do_comp(int argc, const char *argv[]) {
204202
std::vector<std::string_view> pp_defs = split_string_to_views(argv[3], ';');
205203
std::vector<std::string_view> include_dirs = split_string_to_views(argv[4], ';');
206204

207-
auto impl_project = argv[5];
208-
209205
// first ensure that the path to the .xti exists
210206
if (std::error_code err;
211207
!fs::create_directories( fs::path { xt_inst_file_path }.remove_filename(), err )
@@ -221,6 +217,8 @@ int do_comp(int argc, const char *argv[]) {
221217
xt_inst_file xti_old = xti_rw.read();
222218
xt_inst_file xti;
223219

220+
xti.append_version();
221+
224222
// note: the linker needs to have a list of exported symbols
225223
// to match the unresolved symbols against, and ideally
226224
// that information could be embedded in the implementation object files
@@ -230,18 +228,13 @@ int do_comp(int argc, const char *argv[]) {
230228
// then if the link tool appends the template instantiations to the .xti files,
231229
// the implemenation files that include the .xti should get rebuilt next time
232230

233-
// the post-link build rules don't compile specific files,
234-
// (note: there can be more than one implementation file for a particular header)
235-
// they just build the projects which contain files that changed
236-
// so this allows them to associate xti files to projects
237-
xti.append_impl_project(impl_project);
238-
239231
// todo: now we parse the interface header, but we don't really know
240232
// if definitions are actually provided in the impelementation files.
241233
// might be better to parse the implementation file and only emit the defined symbols ?
242-
int ret = find_exported_templates(header_path, pp_defs, include_dirs, [&](const std::string & symbol) {
243-
xti.append_exported_symbol(symbol);
244-
});
234+
int ret = find_exported_templates(header_path, pp_defs, include_dirs,
235+
[&](const std::string & symbol, std::string_view flags) {
236+
xti.append_exported_symbol(symbol, flags);
237+
});
245238

246239
if (ret) return ret;
247240

src/xt_inst_gen/xt_inst_file.h

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct string_view_ref : public string_range
7070
}
7171
};
7272

73-
template<typename Iter>
73+
template<typename Iter, typename OutputType = string_view_ref>
7474
struct string_view_deref_range {
7575
std::string & _str_ref;
7676
Iter _begin, _end;
@@ -80,7 +80,7 @@ struct string_view_deref_range {
8080
Iter _itr;
8181

8282
using iterator_category = typename Iter::iterator_category;
83-
using value_type = string_view_ref;
83+
using value_type = OutputType;
8484
using difference_type = typename Iter::difference_type;
8585
using pointer = value_type *;
8686
using reference = value_type &;
@@ -121,17 +121,28 @@ struct xt_inst_file
121121
{
122122
std::string contents;
123123
// views into the contents:
124-
string_range impl_project { 0, 0 };
125-
std::vector<string_range> exported_symbols;
126-
std::vector<string_range> instantiated_symbols;
127124

128-
auto get_impl_project() {
129-
return impl_project.get(contents);
130-
}
125+
string_range version { 0, 0 };
126+
127+
struct exp_symbol { string_range flags, name; };
128+
129+
struct exp_symbol_ref : public exp_symbol {
130+
std::string & str_ref;
131+
std::string_view get_flags() { return flags.get(str_ref); }
132+
bool has_flag(const char c) { return get_flags().find(c) != std::string_view::npos; }
133+
bool has_flags(std::string_view cs) {
134+
for (const char c : cs) if (!has_flag(c)) return false;
135+
return true;
136+
}
137+
std::string_view get_name() { return name.get(str_ref); }
138+
};
139+
140+
std::vector<exp_symbol> exported_symbols;
141+
std::vector<string_range> instantiated_symbols;
131142

132143
// return a range of string_view_refs
133144
auto get_exported_symbols() {
134-
return string_view_deref_range<decltype(exported_symbols)::iterator> {
145+
return string_view_deref_range<decltype(exported_symbols)::iterator, exp_symbol_ref> {
135146
contents, exported_symbols.begin(), exported_symbols.end()
136147
};
137148
}
@@ -143,38 +154,40 @@ struct xt_inst_file
143154
};
144155
}
145156

146-
string_range append_enclosed_string(
147-
std::string_view before,
148-
std::string_view str,
149-
std::string_view after)
150-
{
151-
contents += before;
157+
string_range append_string(std::string_view str) {
152158
std::size_t pos = contents.size();
153159
contents += str;
154-
contents += after;
155160
return { pos, str.size() };
156161
}
157162

158163
static constexpr std::string_view
159-
project_prefix = "// proj ",
164+
version_prefix = "// ver ",
160165
export_prefix = "// exp ",
161166
instantiation_prefix = "template ";
162167

163-
void append_impl_project(std::string_view project) {
164-
impl_project =
165-
append_enclosed_string(project_prefix, project, "\n");
168+
static constexpr std::string_view
169+
current_version = "1";
170+
171+
void append_version() {
172+
contents += version_prefix;
173+
contents += current_version;
174+
contents += '\n';
166175
}
167176

168-
void append_exported_symbol(std::string_view symbol) {
169-
exported_symbols.emplace_back(
170-
append_enclosed_string(export_prefix, symbol, "\n")
171-
);
177+
void append_exported_symbol(std::string_view symbol, std::string_view flags) {
178+
contents += export_prefix;
179+
auto flags_range = append_string(flags);
180+
contents += ' ';
181+
auto name_range = append_string(symbol);
182+
contents += '\n';
183+
exported_symbols.emplace_back(exp_symbol { flags_range, name_range });
172184
}
173185

174186
void append_instantiated_symbol(std::string_view symbol) {
175-
instantiated_symbols.emplace_back(
176-
append_enclosed_string(instantiation_prefix, symbol, ";\n")
177-
);
187+
contents += instantiation_prefix;
188+
auto symbol_range = append_string(symbol);
189+
contents += ";\n";
190+
instantiated_symbols.emplace_back(symbol_range);
178191
}
179192
};
180193

@@ -202,6 +215,8 @@ struct xt_inst_file_reader_writer
202215
ret.exported_symbols.reserve(nr_lines);
203216
ret.instantiated_symbols.reserve(nr_lines);
204217

218+
std::string_view version;
219+
205220
auto it = ret.contents.begin();
206221
while (it != ret.contents.end()) {
207222
auto it_end = std::find(it, ret.contents.end(), '\n');
@@ -217,10 +232,15 @@ struct xt_inst_file_reader_writer
217232
return false;
218233
};
219234

220-
if (check_and_remove(xt_inst_file::project_prefix)) {
221-
ret.impl_project.set_view(ret.contents, line);
235+
if (check_and_remove(xt_inst_file::version_prefix)) {
236+
version = line;
222237
} else if (check_and_remove(xt_inst_file::export_prefix)) {
223-
ret.exported_symbols.emplace_back(ret.contents, line);
238+
std::string_view flags = line.substr(0, line.find(' '));
239+
std::string_view name = line.substr(flags.size() + 1);
240+
ret.exported_symbols.emplace_back(xt_inst_file::exp_symbol {
241+
string_range { ret.contents, flags },
242+
string_range { ret.contents, name }
243+
});
224244
} else if (check_and_remove(xt_inst_file::instantiation_prefix)) {
225245
line.remove_suffix(1); // for the ; at the end
226246
ret.instantiated_symbols.emplace_back(ret.contents, line);
@@ -230,6 +250,12 @@ struct xt_inst_file_reader_writer
230250
if (it_end == ret.contents.end()) break;
231251
it = it_end + 1;
232252
}
253+
254+
if (version != xt_inst_file::current_version) {
255+
fmt::print("note: version mismatch, ignoring file contents\n");
256+
ret = {};
257+
}
258+
233259
return ret;
234260
}
235261

0 commit comments

Comments
 (0)