Skip to content

Commit 1a33bfd

Browse files
cblichmanncopybara-github
authored andcommitted
clang_generator: Refactor Emitter class to take GeneratorOptions
We need to plumb through the requested SAPI namespace in later changes. Drive-by: - Apply https://abseil.io/tips/116 to emiter and options objects. - Build file cleanups - Cleanup includes PiperOrigin-RevId: 785410056 Change-Id: I056fb1ebbb70215a796543ce5532581f553e16dd
1 parent 1c699cc commit 1a33bfd

6 files changed

Lines changed: 197 additions & 190 deletions

File tree

sandboxed_api/tools/clang_generator/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ cc_library(
4646
copts = sapi_platform_copts(),
4747
deps = [
4848
"//sandboxed_api/util:file_base",
49-
"//sandboxed_api/util:fileops",
5049
"//sandboxed_api/util:status",
5150
"@abseil-cpp//absl/container:btree",
5251
"@abseil-cpp//absl/container:flat_hash_set",
5352
"@abseil-cpp//absl/container:node_hash_set",
5453
"@abseil-cpp//absl/log",
54+
"@abseil-cpp//absl/log:die_if_null",
5555
"@abseil-cpp//absl/random",
5656
"@abseil-cpp//absl/status",
5757
"@abseil-cpp//absl/status:statusor",

sandboxed_api/tools/clang_generator/emitter.cc

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <utility>
1919
#include <vector>
2020

21-
#include "absl/container/btree_set.h"
2221
#include "absl/container/flat_hash_set.h"
2322
#include "absl/log/log.h"
2423
#include "absl/status/status.h"
@@ -30,10 +29,8 @@
3029
#include "absl/strings/str_split.h"
3130
#include "absl/strings/string_view.h"
3231
#include "absl/strings/strip.h"
33-
#include "clang/AST/ASTContext.h"
3432
#include "clang/AST/Decl.h"
3533
#include "clang/AST/DeclBase.h"
36-
#include "clang/AST/DeclCXX.h"
3734
#include "clang/AST/Type.h"
3835
#include "sandboxed_api/tools/clang_generator/diagnostics.h"
3936
#include "sandboxed_api/tools/clang_generator/emitter_base.h"
@@ -152,7 +149,7 @@ absl::StatusOr<std::string> PrintFunctionPrototypeComment(
152149

153150
absl::StatusOr<std::string> Emitter::DoEmitFunction(
154151
const clang::FunctionDecl* decl) {
155-
TypeMapper type_mapper(decl->getASTContext());
152+
TypeMapper type_mapper(decl->getASTContext(), options_.namespace_name);
156153
const clang::QualType return_type = decl->getDeclaredReturnType();
157154

158155
// Skip functions returning record by value.
@@ -231,22 +228,21 @@ absl::StatusOr<std::string> Emitter::DoEmitFunction(
231228
return out;
232229
}
233230

234-
absl::StatusOr<std::string> Emitter::DoEmitHeader(
235-
const GeneratorOptions& options) {
231+
absl::StatusOr<std::string> Emitter::DoEmitHeader() {
236232
// Log a warning message if the number of requested functions is not equal to
237233
// the number of functions generated.
238-
if (!options.function_names.empty() &&
239-
(options.function_names.size() != rendered_functions_ordered_.size())) {
234+
if (!options_.function_names.empty() &&
235+
(options_.function_names.size() != rendered_functions_ordered_.size())) {
240236
LOG(WARNING) << "Generated output has fewer functions than expected - some "
241237
"function signatures might use language features that "
242238
"SAPI does not support. For debugging, we recommend you "
243239
"compare the list of functions in your sapi_library() rule "
244240
"with the generated *.sapi.h file. Expected: "
245-
<< options.function_names.size()
241+
<< options_.function_names.size()
246242
<< ", generated: " << rendered_functions_ordered_.size();
247243
}
248244
std::string out;
249-
const std::string include_guard = GetIncludeGuard(options.out_file);
245+
const std::string include_guard = GetIncludeGuard(options_.out_file);
250246
absl::StrAppend(&out, kHeaderDescription);
251247
absl::StrAppendFormat(&out, kHeaderProlog, include_guard);
252248

@@ -257,64 +253,64 @@ absl::StatusOr<std::string> Emitter::DoEmitHeader(
257253
absl::StrAppend(&out, kHeaderIncludes);
258254

259255
// When embedding the sandboxee, add embed header include
260-
if (!options.embed_name.empty()) {
256+
if (!options_.embed_name.empty()) {
261257
// Not using JoinPath() because even on Windows include paths use plain
262258
// slashes.
263259
std::string include_file(absl::StripSuffix(
264-
absl::StrReplaceAll(options.embed_dir, {{"\\", "/"}}), "/"));
260+
absl::StrReplaceAll(options_.embed_dir, {{"\\", "/"}}), "/"));
265261
if (!include_file.empty()) {
266262
absl::StrAppend(&include_file, "/");
267263
}
268-
absl::StrAppend(&include_file, options.embed_name);
264+
absl::StrAppend(&include_file, options_.embed_name);
269265
absl::StrAppendFormat(&out, kEmbedInclude, include_file);
270266
}
271267

272268
// If specified, wrap the generated API in a namespace
273-
if (options.has_namespace()) {
269+
if (options_.has_namespace()) {
274270
absl::StrAppendFormat(&out, kNamespaceBeginTemplate,
275-
options.namespace_name);
271+
options_.namespace_name);
276272
}
277273

278274
// Emit type dependencies
279275
if (!rendered_types_ordered_.empty()) {
280276
absl::StrAppend(&out, "// Types this API depends on\n");
281-
std::string last_ns_name = options.namespace_name;
277+
std::string last_ns_name = options_.namespace_name;
282278
for (const RenderedType* rt : rendered_types_ordered_) {
283279
const auto& [ns_name, spelling] = *rt;
284280
if (last_ns_name != ns_name) {
285-
if (!last_ns_name.empty() && last_ns_name != options.namespace_name) {
281+
if (!last_ns_name.empty() && last_ns_name != options_.namespace_name) {
286282
absl::StrAppend(&out, "} // namespace ", last_ns_name, "\n\n");
287283
}
288284

289-
if (!ns_name.empty() && ns_name != options.namespace_name) {
285+
if (!ns_name.empty() && ns_name != options_.namespace_name) {
290286
absl::StrAppend(&out, "namespace ", ns_name, " {\n");
291287
}
292288
last_ns_name = ns_name;
293289
}
294290

295291
absl::StrAppend(&out, spelling, ";\n");
296292
}
297-
if (!last_ns_name.empty() && last_ns_name != options.namespace_name) {
293+
if (!last_ns_name.empty() && last_ns_name != options_.namespace_name) {
298294
absl::StrAppend(&out, "} // namespace ", last_ns_name, "\n\n");
299295
}
300296
}
301297

302298
// Optionally emit a default sandbox that instantiates an embedded sandboxee
303-
if (!options.embed_name.empty()) {
299+
if (!options_.embed_name.empty()) {
304300
absl::StrAppendFormat(
305-
&out, kEmbedClassTemplate, absl::StrCat(options.name, "Sandbox"),
306-
absl::StrReplaceAll(options.embed_name, {{"-", "_"}}));
301+
&out, kEmbedClassTemplate, absl::StrCat(options_.name, "Sandbox"),
302+
absl::StrReplaceAll(options_.embed_name, {{"-", "_"}}));
307303
}
308304

309305
// Emit the actual Sandboxed API
310306
absl::StrAppendFormat(&out, kClassHeaderTemplate,
311-
absl::StrCat(options.name, "Api"));
307+
absl::StrCat(options_.name, "Api"));
312308
absl::StrAppend(&out, absl::StrJoin(rendered_functions_ordered_, "\n"));
313309
absl::StrAppend(&out, kClassFooterTemplate);
314310

315311
// Close out the header: close namespace (if needed) and end include guard
316-
if (options.has_namespace()) {
317-
absl::StrAppendFormat(&out, kNamespaceEndTemplate, options.namespace_name);
312+
if (options_.has_namespace()) {
313+
absl::StrAppendFormat(&out, kNamespaceEndTemplate, options_.namespace_name);
318314
}
319315
absl::StrAppendFormat(&out, kHeaderEpilog, include_guard);
320316
return out;
@@ -328,10 +324,9 @@ absl::Status Emitter::AddFunction(clang::FunctionDecl* decl) {
328324
return absl::OkStatus();
329325
}
330326

331-
absl::StatusOr<std::string> Emitter::EmitHeader(
332-
const GeneratorOptions& options) {
333-
SAPI_ASSIGN_OR_RETURN(const std::string header, DoEmitHeader(options));
334-
return internal::ReformatGoogleStyle(options.out_file, header);
327+
absl::StatusOr<std::string> Emitter::EmitHeader() {
328+
SAPI_ASSIGN_OR_RETURN(const std::string header, DoEmitHeader());
329+
return internal::ReformatGoogleStyle(options_.out_file, header);
335330
}
336331

337332
} // namespace sapi

sandboxed_api/tools/clang_generator/emitter.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <string>
1919
#include <vector>
2020

21+
#include "absl/log/die_if_null.h"
2122
#include "absl/status/status.h"
2223
#include "absl/status/statusor.h"
2324
#include "clang/AST/Decl.h"
@@ -31,13 +32,16 @@ namespace sapi {
3132
// Sandboxed API header.
3233
class Emitter : public EmitterBase {
3334
public:
35+
explicit Emitter(const GeneratorOptions* options)
36+
: EmitterBase(), options_(*ABSL_DIE_IF_NULL(options)) {}
37+
3438
// Adds a function to the list of functions to be rendered. In addition, it
3539
// stores the original and SAPI function information for safe drop-in
3640
// generation.
3741
absl::Status AddFunction(clang::FunctionDecl* decl) override;
3842

3943
// Outputs a formatted header for a list of functions and their related types.
40-
absl::StatusOr<std::string> EmitHeader(const GeneratorOptions& options);
44+
absl::StatusOr<std::string> EmitHeader();
4145

4246
protected:
4347
// Rendered function bodies, as a vector to preserve source order. This is
@@ -49,7 +53,9 @@ class Emitter : public EmitterBase {
4953
// documenting the unsandboxed function signature.
5054
absl::StatusOr<std::string> DoEmitFunction(const clang::FunctionDecl* decl);
5155

52-
absl::StatusOr<std::string> DoEmitHeader(const GeneratorOptions& options);
56+
absl::StatusOr<std::string> DoEmitHeader();
57+
58+
const GeneratorOptions& options_;
5359
};
5460

5561
} // namespace sapi

0 commit comments

Comments
 (0)