diff --git a/oi/CMakeLists.txt b/oi/CMakeLists.txt index 1751d23..3754f41 100644 --- a/oi/CMakeLists.txt +++ b/oi/CMakeLists.txt @@ -26,17 +26,20 @@ target_link_libraries(symbol_service dw ) +add_library(features Features.cpp) +target_link_libraries(features glog::glog) + add_library(container_info ContainerInfo.cpp ) target_link_libraries(container_info + features glog::glog toml ) add_library(codegen CodeGen.cpp - Features.cpp FuncGen.cpp OICodeGen.cpp ) diff --git a/oi/CodeGen.cpp b/oi/CodeGen.cpp index b7b113e..19f8de5 100644 --- a/oi/CodeGen.cpp +++ b/oi/CodeGen.cpp @@ -1119,6 +1119,10 @@ bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) { void CodeGen::registerContainer(const fs::path& path) { auto info = std::make_unique(path); + if (info->requiredFeatures != (config_.features & info->requiredFeatures)) { + VLOG(1) << "Skipping container (feature conflict): " << info->typeName; + return; + } VLOG(1) << "Registered container: " << info->typeName; containerInfos_.emplace_back(std::move(info)); } diff --git a/oi/ContainerInfo.cpp b/oi/ContainerInfo.cpp index 7d3d9ff..a5703be 100644 --- a/oi/ContainerInfo.cpp +++ b/oi/ContainerInfo.cpp @@ -242,6 +242,19 @@ ContainerInfo::ContainerInfo(const fs::path& path) { underlyingContainerIndex = info["underlying_container_index"].value(); + if (toml::array* arr = info["required_features"].as_array()) { + arr->for_each([&](auto&& el) { + if constexpr (toml::is_string) { + oi::detail::Feature f = oi::detail::featureFromStr(*el); + if (f == oi::detail::Feature::UnknownFeature) { + LOG(WARNING) << "unknown feature in container config: " << el; + return; + } + requiredFeatures[f] = true; + } + }); + } + if (!container["codegen"].is_table()) { throw ContainerInfoError( path, "a container info file requires a `codegen` table"); diff --git a/oi/ContainerInfo.h b/oi/ContainerInfo.h index 776ab57..0ad9da9 100644 --- a/oi/ContainerInfo.h +++ b/oi/ContainerInfo.h @@ -22,6 +22,7 @@ #include #include "oi/ContainerTypeEnum.h" +#include "oi/Features.h" ContainerTypeEnum containerTypeEnumFromStr(std::string& str); const char* containerTypeEnumToStr(ContainerTypeEnum ty); @@ -94,6 +95,7 @@ struct ContainerInfo { std::optional underlyingContainerIndex{}; std::vector stubTemplateParams{}; bool captureKeys = false; + oi::detail::FeatureSet requiredFeatures; Codegen codegen; diff --git a/oi/EnumBitset.h b/oi/EnumBitset.h index 96b798b..d9828ee 100644 --- a/oi/EnumBitset.h +++ b/oi/EnumBitset.h @@ -47,11 +47,26 @@ class EnumBitset { return bitset.none(); } + bool operator==(const EnumBitset& that) const { + return bitset == that.bitset; + } EnumBitset& operator|=(const EnumBitset& that) { bitset |= that.bitset; return *this; } + EnumBitset& operator&=(const EnumBitset& that) { + bitset &= that.bitset; + return *this; + } private: BitsetType bitset; }; + +template +EnumBitset operator&(const EnumBitset& lhs, + const EnumBitset& rhs) { + auto out = lhs; + out &= rhs; + return out; +} diff --git a/test/integration/thrift_isset.toml b/test/integration/thrift_isset.toml index e32f416..064cb13 100644 --- a/test/integration/thrift_isset.toml +++ b/test/integration/thrift_isset.toml @@ -213,7 +213,6 @@ namespace cpp2 { ]}]''' [cases.no_capture] - oil_skip = 'oil does not support thrift isset yet' # https://github.com/facebookexperimental/object-introspection/issues/296 param_types = ["const cpp2::MyThriftStructBoxed&"] setup = ''' cpp2::MyThriftStructBoxed ret; diff --git a/types/README.md b/types/README.md index 1b70b4b..ebde86c 100644 --- a/types/README.md +++ b/types/README.md @@ -22,6 +22,13 @@ This document describes the format of the container definition files contained i Only used for container adapters. Points OI to the template parameter representing the underlying container to be measured. +- `required_features` + + A set of feature names such as `tree-builder-v2` which must be enabled for + this container description to be included. Currently only supported with + CodeGen v2 as that's their only use case and an implementation for CodeGen v1 + would be untested. + ### codegen - `decl` diff --git a/types/thrift_isset_type.toml b/types/thrift_isset_type.toml index edbc118..213cb58 100644 --- a/types/thrift_isset_type.toml +++ b/types/thrift_isset_type.toml @@ -2,6 +2,7 @@ type_name = "apache::thrift::detail::isset_bitset" ctype = "THRIFT_ISSET_TYPE" header = "thrift/lib/cpp2/gen/module_types_h.h" +required_features = ["capture-thrift-isset"] # Old: typeName = "apache::thrift::detail::isset_bitset<"