Skip to content

Commit

Permalink
Internal change
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 648342169
Change-Id: I0c2bc134f378245d5784573a2d768e4fd2b6959f
  • Loading branch information
okunz authored and copybara-github committed Jul 1, 2024
1 parent 35b7ccf commit 0fca707
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 4 deletions.
10 changes: 10 additions & 0 deletions sandboxed_api/tools/clang_generator/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,24 @@ cc_library(
"emitter.cc",
"emitter_base.cc",
"generator.cc",
# sapi::google3-begin(internal feature only)
"safe_replacement_emitter.cc",
# sapi::google3-end
"types.cc",
],
hdrs = [
"diagnostics.h",
"emitter.h",
"emitter_base.h",
"generator.h",
# sapi::google3-begin(internal feature only)
"safe_replacement_emitter.h",
# sapi::google3-end
"types.h",
],
copts = sapi_platform_copts(),
deps = [
"//sandboxed_api/util:file_base",
"//sandboxed_api/util:status",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/container:node_hash_set",
Expand Down Expand Up @@ -64,6 +71,9 @@ cc_test(
"emitter_test.cc",
"frontend_action_test_util.cc",
"frontend_action_test_util.h",
# sapi::google3-begin(internal feature only)
"safe_replacement_emitter_test.cc",
# sapi::google3-end
],
copts = sapi_platform_copts(),
deps = [
Expand Down
4 changes: 4 additions & 0 deletions sandboxed_api/tools/clang_generator/generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ struct GeneratorOptions {
absl::flat_hash_set<std::string> function_names;
absl::flat_hash_set<std::string> in_files;
bool limit_scan_depth = false;
// sapi::google3-begin(internal feature only)
bool safe_wrapper_gen = false;
bool force_safe_wrapper = false;
// sapi::google3-end

// Output options
std::string work_dir;
Expand Down
70 changes: 66 additions & 4 deletions sandboxed_api/tools/clang_generator/generator_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#include "absl/base/attributes.h"
#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h" // sapi::google3-only(internal feature only)
#include "absl/strings/str_format.h"
#include "absl/strings/str_replace.h" // sapi::google3-only(internal feature only)
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
Expand All @@ -29,6 +31,7 @@
#include "sandboxed_api/tools/clang_generator/compilation_database.h"
#include "sandboxed_api/tools/clang_generator/emitter.h"
#include "sandboxed_api/tools/clang_generator/generator.h"
#include "sandboxed_api/tools/clang_generator/safe_replacement_emitter.h" // sapi::google3-only(internal feature only)
#include "sandboxed_api/util/file_helpers.h"
#include "sandboxed_api/util/fileops.h"
#include "sandboxed_api/util/path.h"
Expand All @@ -44,8 +47,8 @@ static auto* g_common_help =
new llvm::cl::extrahelp(clang::tooling::CommonOptionsParser::HelpMessage);
static auto* g_extra_help = new llvm::cl::extrahelp(
"Full documentation at: "
"https://developers.google.com/code-sandboxing/sandboxed-api\n"
"Report bugs to https://github.com/google/sandboxed-api/issues\n");
"<https://developers.google.com/code-sandboxing/sandboxed-api>\n"
"Report bugs to <https://github.com/google/sandboxed-api/issues>\n");

// Command line options
static auto* g_sapi_embed_dir = new llvm::cl::opt<std::string>(
Expand Down Expand Up @@ -87,10 +90,20 @@ static auto* g_sapi_out = new llvm::cl::opt<std::string>(
"Output path of the generated header. If empty, simply appends .sapi.h "
"to the basename of the first source file specified."),
llvm::cl::cat(*g_tool_category));
// sapi::google3-begin(internal feature only)
static auto* g_safe_wrapper_gen = new llvm::cl::opt<bool>(
"safe_wrapper_gen",
llvm::cl::desc("Whether to generate a safe drop-in replacement library."),
llvm::cl::cat(*g_tool_category));
static auto* g_force_safe_wrapper = new llvm::cl::opt<bool>(
"force_safe_wrapper",
llvm::cl::desc("Whether to overwrite an existing safe drop-in "
"replacement library in the active workspace."),
llvm::cl::cat(*g_tool_category));
// sapi::google3-end

} // namespace

// Returns a GeneratorOptions object based on the command-line flags.
GeneratorOptions GeneratorOptionsFromFlags(
const std::vector<std::string>& sources) {
GeneratorOptions options;
Expand All @@ -110,6 +123,10 @@ GeneratorOptions GeneratorOptionsFromFlags(
!g_sapi_out->empty() ? *g_sapi_out : GetOutputFilename(sources.front());
options.embed_dir = *g_sapi_embed_dir;
options.embed_name = *g_sapi_embed_name;
// sapi::google3-begin(internal feature only)
options.safe_wrapper_gen = *g_safe_wrapper_gen;
options.force_safe_wrapper = *g_force_safe_wrapper;
// sapi::google3-end
return options;
}

Expand All @@ -132,7 +149,6 @@ absl::Status GeneratorMain(int argc, char* argv[]) {
}

auto options = sapi::GeneratorOptionsFromFlags(sources);
sapi::Emitter emitter;

std::unique_ptr<clang::tooling::CompilationDatabase> db =
FromCxxAjustedCompileCommands(
Expand All @@ -145,6 +161,52 @@ absl::Status GeneratorMain(int argc, char* argv[]) {
"Note: Ignoring deprecated command-line option: sapi_isystem\n");
}

// sapi::google3-begin(internal feature only)
// Process safe drop-in generation.
if (options.safe_wrapper_gen) {
sapi::SafeReplacementEmitter safe_emitter;
std::string base_file_path = file::JoinPath(
options.embed_dir,
StringReplace(options.embed_name, "sandboxed_", "safe_", false));
std::string safe_wrapper_header_path = absl::StrCat(base_file_path, ".h");
std::string safe_wrapper_implementation_path =
absl::StrCat(base_file_path, ".cc");

if (sapi::file_util::fileops::Exists(safe_wrapper_header_path,
/*fully_resolve=*/true) ||
sapi::file_util::fileops::Exists(safe_wrapper_implementation_path,
/*fully_resolve=*/true)) {
if (!options.force_safe_wrapper) {
return absl::UnknownError(
"Error: Safe drop-in replacement library already exists. To "
"overwrite it, use the --force_safe_wrapper option.");
}
}

if (int result = tool.run(
std::make_unique<sapi::GeneratorFactory>(safe_emitter, options)
.get());
result != 0) {
return absl::UnknownError("Error: Header generation failed.");
}

SAPI_ASSIGN_OR_RETURN(std::string safe_wrapper_header,
safe_emitter.EmitSafeDropInHeader(options));
SAPI_RETURN_IF_ERROR(sapi::file::SetContents(
safe_wrapper_header_path, safe_wrapper_header, sapi::file::Defaults()));

SAPI_ASSIGN_OR_RETURN(std::string safe_wrapper_implementation,
safe_emitter.EmitSafeDropInImplementation(options));
SAPI_RETURN_IF_ERROR(sapi::file::SetContents(
safe_wrapper_implementation_path, safe_wrapper_implementation,
sapi::file::Defaults()));

return absl::OkStatus();
}
// sapi::google3-end

// Process SAPI header generation.
sapi::Emitter emitter;
if (int result = tool.run(
std::make_unique<sapi::GeneratorFactory>(emitter, options).get());
result != 0) {
Expand Down
32 changes: 32 additions & 0 deletions sandboxed_api/tools/clang_generator/types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,36 @@ std::string MapQualTypeReturn(const clang::ASTContext& context,
">");
}

// sapi::google3-begin(internal feature only)
std::string MapQualTypeSapiVariable(const clang::ASTContext& context,
clang::QualType qual) {
// For pointers, we need to get the pointee type.
if (IsPointerOrReference(qual)) {
const clang::PointerType& ptr_type = *qual->getAs<clang::PointerType>();
// We only extract the pointee type if it is a builtin type and not a char.
if (clang::QualType pointee_type = ptr_type.getPointeeType();
pointee_type->isBuiltinType() && !pointee_type->isCharType()) {
return MapQualType(context, pointee_type);
}
}
// The parameter is not a pointer, return the original type.
return MapQualTypeParameterForCxx(context, qual);
}

std::string MapQualTypeSapiBufferVariable(const clang::ASTContext& context,
clang::QualType qual) {
// For pointers, we need to get the pointee type.
if (IsPointerOrReference(qual)) {
const clang::PointerType& ptr_type = *qual->getAs<clang::PointerType>();
// We only extract the pointee type if it is a builtin type and not a char.
if (clang::QualType pointee_type = ptr_type.getPointeeType();
pointee_type->isBuiltinType() && pointee_type->isCharType()) {
return absl::StrCat("sapi::v::Array<", pointee_type.getAsString(), ">");
}
}
// The parameter is not a pointer, return the original type.
return MapQualTypeParameterForCxx(context, qual);
}
// sapi::google3-end

} // namespace sapi
19 changes: 19 additions & 0 deletions sandboxed_api/tools/clang_generator/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,25 @@ std::string MapQualTypeParameter(const clang::ASTContext& context,
std::string MapQualTypeReturn(const clang::ASTContext& context,
clang::QualType qual);

// sapi::google3-begin(internal feature only)
// Maps, if possible, a qualified type to a fully qualified SAPI-compatible
// variable type by calling MapyQualType. Whenever this is not possible, the
// function maps to a fully qualified C++ type name by calling
// MapQualTypeParameterForCxx.
// Important: This function should only be used for the safe drop-in replacement
// generator.
std::string MapQualTypeSapiVariable(const clang::ASTContext& context,
clang::QualType qual);

// Maps, if possible, a qualified type to a `sapi::v::Array<T>` variable type
// Whenever this is not possible, the function maps to a fully qualified C++
// type name by calling MapQualTypeParameterForCxx.
// Important: This function should only be used for the safe drop-in replacement
// generator.
std::string MapQualTypeSapiBufferVariable(const clang::ASTContext& context,
clang::QualType qual);
// sapi::google3-end

} // namespace sapi

#endif // SANDBOXED_API_TOOLS_CLANG_GENERATOR_TYPES_H_

0 comments on commit 0fca707

Please sign in to comment.