From 39a1bc9d7ac2c5122fb7291ac7d9c909f0615f91 Mon Sep 17 00:00:00 2001 From: Christian Blichmann Date: Mon, 5 Sep 2022 07:14:55 -0700 Subject: [PATCH] Skip system headers in Clang generator When not requesting any particular function, `sapi_library()` will try and make available _all_ functions it finds. In this case, system headers should be skipped to avoid inflating the API surface. Standard library functions can still be manually requested by adding them to the `functions` (Bazel)/ `FUNCTIONS` (CMake) argument. PiperOrigin-RevId: 472272506 Change-Id: I8f8d79796d3044e598eebb7f87ce4cf464b47ed7 --- .../tools/clang_generator/emitter_test.cc | 12 ++++----- .../tools/clang_generator/generator.cc | 25 ++++++++++++++----- .../tools/clang_generator/generator.h | 6 ++--- .../tools/clang_generator/generator_tool.cc | 2 +- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/sandboxed_api/tools/clang_generator/emitter_test.cc b/sandboxed_api/tools/clang_generator/emitter_test.cc index 550765b..bf51662 100644 --- a/sandboxed_api/tools/clang_generator/emitter_test.cc +++ b/sandboxed_api/tools/clang_generator/emitter_test.cc @@ -52,7 +52,7 @@ TEST_F(EmitterTest, BasicFunctionality) { EmitterForTesting emitter; RunFrontendAction(R"(extern "C" void ExposedFunction() {})", - absl::make_unique(emitter, options)); + std::make_unique(emitter, options)); EXPECT_THAT(emitter.functions_, SizeIs(1)); @@ -80,7 +80,7 @@ TEST_F(EmitterTest, RelatedTypes) { typedef struct { int member; } MyStruct; extern "C" void Structize(MyStruct* s); )", - absl::make_unique(emitter, GeneratorOptions())); + std::make_unique(emitter, GeneratorOptions())); // Types from "std" should be skipped EXPECT_THAT(emitter.rendered_types_["std"], IsEmpty()); @@ -106,7 +106,7 @@ TEST_F(EmitterTest, NestedStruct) { }; extern "C" void Structize(A* s); )", - absl::make_unique(emitter, GeneratorOptions())); + std::make_unique(emitter, GeneratorOptions())); EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]), ElementsAre("struct A {" @@ -125,7 +125,7 @@ TEST_F(EmitterTest, NestedAnonymousStruct) { }; extern "C" void Structize(A* s); )", - absl::make_unique(emitter, GeneratorOptions())); + std::make_unique(emitter, GeneratorOptions())); EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]), ElementsAre("struct A {" @@ -144,7 +144,7 @@ TEST_F(EmitterTest, ParentNotCollected) { }; extern "C" void Structize(A::B* s); )", - absl::make_unique(emitter, GeneratorOptions())); + std::make_unique(emitter, GeneratorOptions())); EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]), ElementsAre("struct A {" @@ -160,7 +160,7 @@ TEST_F(EmitterTest, RemoveQualifiers) { struct A { int data; }; extern "C" void Structize(const A* in, A* out); )", - absl::make_unique(emitter, GeneratorOptions())); + std::make_unique(emitter, GeneratorOptions())); EXPECT_THAT(UglifyAll(emitter.rendered_types_[""]), ElementsAre("struct A { int data; }")); diff --git a/sandboxed_api/tools/clang_generator/generator.cc b/sandboxed_api/tools/clang_generator/generator.cc index 0ffc157..20b3680 100644 --- a/sandboxed_api/tools/clang_generator/generator.cc +++ b/sandboxed_api/tools/clang_generator/generator.cc @@ -48,12 +48,25 @@ std::string GetOutputFilename(absl::string_view source_file) { } bool GeneratorASTVisitor::VisitFunctionDecl(clang::FunctionDecl* decl) { - if (!decl->isCXXClassMember() && // Skip classes - decl->isExternC() && // Skip non external functions - !decl->isTemplated() && // Skip function templates - // Process either all function or just the requested ones - (options_.function_names.empty() || - options_.function_names.count(ToStringView(decl->getName())) > 0)) { + if (decl->isCXXClassMember() || // Skip classes + !decl->isExternC() || // Skip non external functions + decl->isTemplated() // Skip function templates + ) { + return true; + } + + // Process either all function or just the requested ones + if (bool all_functions = options_.function_names.empty(); + all_functions || + options_.function_names.count(ToStringView(decl->getName())) > 0) { + // Skip functions from system headers when all functions are requested. + // This allows to still specify standard library functions explicitly. + if (all_functions && + decl->getASTContext().getSourceManager().isInSystemHeader( + decl->getBeginLoc())) { + return true; + } + functions_.push_back(decl); collector_.CollectRelatedTypes(decl->getDeclaredReturnType()); diff --git a/sandboxed_api/tools/clang_generator/generator.h b/sandboxed_api/tools/clang_generator/generator.h index 2b211b0..9881905 100644 --- a/sandboxed_api/tools/clang_generator/generator.h +++ b/sandboxed_api/tools/clang_generator/generator.h @@ -97,8 +97,8 @@ class GeneratorAction : public clang::ASTFrontendAction { private: std::unique_ptr CreateASTConsumer( clang::CompilerInstance&, llvm::StringRef in_file) override { - return absl::make_unique(std::string(in_file), - emitter_, options_); + return std::make_unique(std::string(in_file), + emitter_, options_); } bool hasCodeCompletionSupport() const override { return false; } @@ -116,7 +116,7 @@ class GeneratorFactory : public clang::tooling::FrontendActionFactory { private: #if LLVM_VERSION_MAJOR >= 10 std::unique_ptr create() override { - return absl::make_unique(emitter_, options_); + return std::make_unique(emitter_, options_); } #else clang::FrontendAction* create() override { diff --git a/sandboxed_api/tools/clang_generator/generator_tool.cc b/sandboxed_api/tools/clang_generator/generator_tool.cc index f155198..578e103 100644 --- a/sandboxed_api/tools/clang_generator/generator_tool.cc +++ b/sandboxed_api/tools/clang_generator/generator_tool.cc @@ -136,7 +136,7 @@ absl::Status GeneratorMain(int argc, char* argv[]) { } if (int result = tool.run( - absl::make_unique(emitter, options).get()); + std::make_unique(emitter, options).get()); result != 0) { return absl::UnknownError("header generation failed"); }