20 | void getSizeType(const %1% &container, size_t& returnArg)
21 | {
22 | SAVE_SIZE(sizeof(%1%
) - sizeof(P) - sizeof(Q));
23 |
24 | getSizeType(container.first, returnArg);
25 | getSizeType(container.second, returnArg);
26 | }
27 | """
28 |
29 | traversal_func = """
30 | return OIInternal::getSizeType(ctx,
31 | container.second,
32 | returnArg.delegate([&ctx, &container](auto ret) {
33 | return OIInternal::getSizeType(ctx, container.first, ret);
34 | })
35 | );
36 | """
37 |
38 | [[codegen.processor]]
39 | type = "types::st::Pair::type, typename TypeHandler::type>"
40 | func = """
41 | static constexpr auto firstField = make_field("first");
42 | static constexpr auto secondField = make_field("second");
43 |
44 | el.exclusive_size = sizeof(std::pair) - sizeof(T0) - sizeof(T1);
45 | stack_ins(secondField);
46 | stack_ins(firstField);
47 | """
48 |
--------------------------------------------------------------------------------
/website/static/img/OISymbol.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/oi/type_graph/RemoveTopLevelPointer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 | #include
20 |
21 | #include "PassManager.h"
22 | #include "Types.h"
23 | #include "Visitor.h"
24 |
25 | namespace oi::detail::type_graph {
26 |
27 | /*
28 | * RemoveTopLevelPointer
29 | *
30 | * If the top type node is a pointer, remove it from the graph and instead have
31 | * the pointee type as the top-level node.
32 | */
33 | class RemoveTopLevelPointer : public LazyVisitor {
34 | public:
35 | static Pass createPass();
36 |
37 | void removeTopLevelPointers(std::vector>& types);
38 | void visit(Pointer& p) override;
39 | void visit(Reference& r) override;
40 |
41 | private:
42 | Type* topLevelType_ = nullptr;
43 | };
44 |
45 | } // namespace oi::detail::type_graph
46 |
--------------------------------------------------------------------------------
/test/integration/folly_shims.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | namespace folly {
6 | namespace detail {
7 |
8 | // The FOLLY_SAFE_DCHECK macro is peppered throughout the folly headers. When
9 | // building in release mode this macro does nothing, but in debug builds it
10 | // requires safe_assert_terminate() to be defined. To avoid building and
11 | // linking against folly, we define our own no-op version of this function here.
12 | template <>
13 | void safe_assert_terminate(safe_assert_arg const* /*arg*/,
14 | ...) noexcept {
15 | abort();
16 | }
17 |
18 | template <>
19 | void safe_assert_terminate(safe_assert_arg const* /*arg*/, ...) noexcept {
20 | abort();
21 | }
22 |
23 | void ScopeGuardImplBase::terminate() noexcept {
24 | abort();
25 | }
26 |
27 | } // namespace detail
28 |
29 | namespace f14 {
30 | namespace detail {
31 |
32 | void F14LinkCheck::check() noexcept {
33 | }
34 |
35 | bool tlsPendingSafeInserts(std::ptrdiff_t /*delta*/) {
36 | /* Disable extra debugging re-hash by classifying all inserts as safe (return
37 | * true) */
38 | return true;
39 | }
40 |
41 | std::size_t tlsMinstdRand(std::size_t /*n*/) {
42 | /* Disable insert order perturbation by always returning 0 */
43 | return 0;
44 | }
45 |
46 | } // namespace detail
47 | } // namespace f14
48 |
49 | } // namespace folly
50 |
--------------------------------------------------------------------------------
/oi/type_graph/EnforceCompatibility.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 |
20 | #include "NodeTracker.h"
21 | #include "PassManager.h"
22 | #include "Types.h"
23 | #include "Visitor.h"
24 |
25 | namespace oi::detail::type_graph {
26 |
27 | /*
28 | * EnforceCompatibility
29 | *
30 | * Transforms the type graph so that CodeGen produces code which is compatible
31 | * with OICodeGen.
32 | */
33 | class EnforceCompatibility : public RecursiveVisitor {
34 | public:
35 | static Pass createPass();
36 |
37 | EnforceCompatibility(NodeTracker& tracker) : tracker_(tracker) {
38 | }
39 |
40 | using RecursiveVisitor::accept;
41 |
42 | void accept(Type& type) override;
43 | void visit(Class& c) override;
44 |
45 | private:
46 | NodeTracker& tracker_;
47 | };
48 |
49 | } // namespace oi::detail::type_graph
50 |
--------------------------------------------------------------------------------
/test/TypeGraphParser.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "oi/type_graph/Types.h"
7 |
8 | namespace oi::detail::type_graph {
9 | class TypeGraph;
10 | } // namespace oi::detail::type_graph
11 |
12 | using namespace oi::detail::type_graph;
13 |
14 | /*
15 | * TypeGraphParser
16 | *
17 | * Parses a textual type graph, as emitted by Printer.
18 | */
19 | class TypeGraphParser {
20 | public:
21 | TypeGraphParser(TypeGraph& typeGraph) : typeGraph_(typeGraph) {
22 | }
23 |
24 | void parse(std::string_view input);
25 |
26 | private:
27 | TypeGraph& typeGraph_;
28 | std::unordered_map> nodesById_;
29 |
30 | Type& parseType(std::string_view& input, size_t rootIndent);
31 | template
32 | void parseParams(T& c, std::string_view& input, size_t rootIndent);
33 | void parseParents(Class& c, std::string_view& input, size_t rootIndent);
34 | void parseMembers(Class& c, std::string_view& input, size_t rootIndent);
35 | void parseFunctions(Class& c, std::string_view& input, size_t rootIndent);
36 | void parseChildren(Class& c, std::string_view& input, size_t rootIndent);
37 | void parseUnderlying(Container& c,
38 | std::string_view& input,
39 | size_t rootIndent);
40 | };
41 |
42 | class TypeGraphParserError : public std::runtime_error {
43 | public:
44 | TypeGraphParserError(const std::string& msg) : std::runtime_error{msg} {
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/types/optional_type.toml:
--------------------------------------------------------------------------------
1 | [info]
2 | type_name = "std::optional"
3 | ctype = "OPTIONAL_TYPE"
4 | header = "optional"
5 |
6 | # Old:
7 | typeName = "std::optional<"
8 | ns = ["namespace std"]
9 | numTemplateParams = 1
10 |
11 | [codegen]
12 | decl = """
13 | template
14 | void getSizeType(const %1% &container, size_t& returnArg);
15 | """
16 |
17 | func = """
18 | template
19 | void getSizeType(const %1%& container, size_t& returnArg) {
20 | if (container) {
21 | SAVE_SIZE(sizeof(%1%) - sizeof(T));
22 | SAVE_DATA(true);
23 | getSizeType(*container, returnArg);
24 | } else {
25 | SAVE_SIZE(sizeof(%1%));
26 | SAVE_DATA(false);
27 | }
28 | }
29 | """
30 |
31 | traversal_func = """
32 | if (container.has_value()) {
33 | return returnArg.template delegate<1>([&ctx, &container](auto ret) {
34 | return OIInternal::getSizeType(ctx, *container, ret);
35 | });
36 | } else {
37 | return returnArg.template delegate<0>(std::identity());
38 | }
39 | """
40 |
41 | [[codegen.processor]]
42 | type = "types::st::Sum, typename TypeHandler::type>"
43 | func = """
44 | static constexpr auto elementField = make_field("el");
45 |
46 | auto sum = std::get(d.val);
47 |
48 | el.container_stats = result::Element::ContainerStats {
49 | .capacity = 1,
50 | .length = sum.index,
51 | };
52 |
53 | if (sum.index == 1) {
54 | el.exclusive_size -= sizeof(T0);
55 | stack_ins(elementField);
56 | }
57 | """
58 |
--------------------------------------------------------------------------------
/oi/type_graph/Prune.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 | #include
20 |
21 | #include "NodeTracker.h"
22 | #include "PassManager.h"
23 | #include "Types.h"
24 | #include "Visitor.h"
25 |
26 | namespace oi::detail::type_graph {
27 |
28 | /*
29 | * Prune
30 | *
31 | * Removes unnecessary information from a type graph and releases memory where
32 | * possible.
33 | */
34 | class Prune : public RecursiveVisitor {
35 | public:
36 | static Pass createPass();
37 |
38 | Prune(NodeTracker& tracker) : tracker_(tracker) {
39 | }
40 |
41 | using RecursiveVisitor::accept;
42 | using RecursiveVisitor::visit;
43 |
44 | void accept(Type& type) override;
45 | void visit(Class& c) override;
46 | void visit(Container& c) override;
47 |
48 | private:
49 | NodeTracker& tracker_;
50 | };
51 |
52 | } // namespace oi::detail::type_graph
53 |
--------------------------------------------------------------------------------
/oi/type_graph/AlignmentCalc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "PassManager.h"
23 | #include "Types.h"
24 | #include "Visitor.h"
25 |
26 | namespace oi::detail::type_graph {
27 |
28 | /*
29 | * AlignmentCalc
30 | *
31 | * Calculates alignment information for types TODO finish comment
32 | */
33 | class AlignmentCalc final : public RecursiveVisitor {
34 | public:
35 | static Pass createPass();
36 |
37 | void calculateAlignments(
38 | const std::vector>& types);
39 |
40 | using RecursiveVisitor::accept;
41 |
42 | void accept(Type& type) override;
43 | void visit(Class& c) override;
44 | void visit(Container& c) override;
45 |
46 | private:
47 | std::unordered_set visited_;
48 | };
49 |
50 | } // namespace oi::detail::type_graph
51 |
--------------------------------------------------------------------------------
/test/integration/inheritance_multiple.toml:
--------------------------------------------------------------------------------
1 | definitions = '''
2 | struct Base_1 {
3 | int a;
4 | };
5 | struct Base_2 {
6 | int b;
7 | };
8 | struct Base_3 {
9 | int c;
10 | };
11 | struct Derived_1: Base_2, Base_3 {
12 | int d;
13 | };
14 | struct Base_4 {
15 | int e;
16 | };
17 | struct Derived_2: Base_1, Derived_1, Base_4 {
18 | int f;
19 | };
20 | '''
21 |
22 | [cases]
23 | [cases.a]
24 | param_types = ["const Derived_2&"]
25 | setup = 'return {};'
26 | expect_json = '''[{
27 | "staticSize":24,
28 | "dynamicSize":0,
29 | "members":[
30 | {"name":"a", "staticSize":4, "dynamicSize":0},
31 | {"name":"b", "staticSize":4, "dynamicSize":0},
32 | {"name":"c", "staticSize":4, "dynamicSize":0},
33 | {"name":"d", "staticSize":4, "dynamicSize":0},
34 | {"name":"e", "staticSize":4, "dynamicSize":0},
35 | {"name":"f", "staticSize":4, "dynamicSize":0}
36 | ]}]'''
37 | expect_json_v2 = '''[{
38 | "staticSize":24,
39 | "exclusiveSize":0,
40 | "size":24,
41 | "members":[
42 | {"name":"a", "staticSize":4, "exclusiveSize":4, "size":4},
43 | {"name":"b", "staticSize":4, "exclusiveSize":4, "size":4},
44 | {"name":"c", "staticSize":4, "exclusiveSize":4, "size":4},
45 | {"name":"d", "staticSize":4, "exclusiveSize":4, "size":4},
46 | {"name":"e", "staticSize":4, "exclusiveSize":4, "size":4},
47 | {"name":"f", "staticSize":4, "exclusiveSize":4, "size":4}
48 | ]}]'''
49 |
--------------------------------------------------------------------------------
/test/integration/references.toml:
--------------------------------------------------------------------------------
1 | includes = ["vector"]
2 | definitions = '''
3 | struct IntRef {
4 | int &n;
5 | };
6 | struct VectorRef {
7 | std::vector &vec;
8 | };
9 | '''
10 | [cases]
11 | [cases.int_ref]
12 | skip = "references are being treated as raw pointers" # https://github.com/facebookexperimental/object-introspection/issues/16
13 | param_types = ["const IntRef&"]
14 | setup = "return {{*new int(1)}};"
15 | expect_json = '''[{
16 | "staticSize":8,
17 | "dynamicSize":4,
18 | "members":[
19 | {
20 | "typeName": "int &",
21 | "name": "n",
22 | "staticSize": 8,
23 | "dynamicSize": 4
24 | }
25 | ]}]'''
26 | [cases.vector_ref]
27 | skip = "references are being treated as raw pointers" # https://github.com/facebookexperimental/object-introspection/issues/16
28 | param_types = ["const VectorRef&"]
29 | setup = "return {{*new std::vector{1,2,3}}};"
30 | expect_json = '''[{
31 | "staticSize":8,
32 | "dynamicSize":36,
33 | "members":[
34 | {
35 | "typeName": "std::vector &",
36 | "name": "vec",
37 | "staticSize": 8,
38 | "dynamicSize": 36,
39 | "members": [
40 | {
41 | "typeName": "std::vector",
42 | "staticSize":24,
43 | "dynamicSize":12,
44 | "length":3,
45 | "capacity":3,
46 | "elementStaticSize":4
47 | }
48 | ]
49 | }
50 | ]}]'''
51 |
--------------------------------------------------------------------------------
/types/array_type.toml:
--------------------------------------------------------------------------------
1 | [info]
2 | type_name = "std::array"
3 | ctype = "ARRAY_TYPE"
4 | header = "array"
5 |
6 | # Old:
7 | numTemplateParams = 1
8 | ns = ["namespace std"]
9 | typeName = "std::array<"
10 |
11 | [codegen]
12 | decl = """
13 | template
14 | void getSizeType(const %1% &container, size_t& returnArg);
15 | """
16 |
17 | func = """
18 | template
19 | void getSizeType(const %1% &container, size_t& returnArg)
20 | {
21 | SAVE_DATA((uintptr_t)container.size());
22 | SAVE_SIZE(sizeof(container));
23 |
24 | for (auto & it: container) {
25 | // undo the static size that has already been added per-element
26 | SAVE_SIZE(-sizeof(it));
27 | getSizeType(it, returnArg);
28 | }
29 | }
30 | """
31 |
32 | traversal_func = """
33 | auto tail = returnArg.write(container.size());
34 |
35 | for (auto & it: container) {
36 | tail = tail.delegate([&ctx, &it](auto ret) {
37 | return TypeHandler::getSizeType(ctx, it, ret);
38 | });
39 | }
40 |
41 | return tail.finish();
42 | """
43 |
44 | [[codegen.processor]]
45 | type = "types::st::List::type>"
46 | func = """
47 | static constexpr auto childField = make_field("[]");
48 |
49 | size_t size = std::get(d.val).length;
50 | el.exclusive_size = N0 == 0 ? 1 : 0;
51 | el.container_stats.emplace(result::Element::ContainerStats{ .capacity = size, .length = size });
52 | for (size_t i = 0; i < size; i++)
53 | stack_ins(childField);
54 | """
55 |
--------------------------------------------------------------------------------
/types/folly_optional_type.toml:
--------------------------------------------------------------------------------
1 | [info]
2 | type_name = "folly::Optional"
3 | ctype = "FOLLY_OPTIONAL_TYPE"
4 | header = "folly/Optional.h"
5 |
6 | # Old:
7 | typeName = "folly::Optional<"
8 | ns = ["folly::Optional"]
9 | numTemplateParams = 1
10 | replaceTemplateParamIndex = []
11 |
12 | [codegen]
13 | decl = """
14 | template
15 | void getSizeType(const %1% &container, size_t& returnArg);
16 | """
17 |
18 | func = """
19 | template
20 | void getSizeType(const %1%& container, size_t& returnArg) {
21 | if (container) {
22 | SAVE_SIZE(sizeof(%1%) - sizeof(T));
23 | SAVE_DATA((uintptr_t)(container.get_pointer()));
24 |
25 | getSizeType(*(container.get_pointer()), returnArg);
26 | } else {
27 | SAVE_SIZE(sizeof(%1%));
28 | SAVE_DATA(0);
29 | }
30 | }
31 | """
32 |
33 | traversal_func = """
34 | if (container.has_value()) {
35 | return returnArg.template delegate<1>([&ctx, &container](auto ret) {
36 | return OIInternal::getSizeType(ctx, *container, ret);
37 | });
38 | } else {
39 | return returnArg.template delegate<0>(std::identity());
40 | }
41 | """
42 |
43 | [[codegen.processor]]
44 | type = "types::st::Sum, typename TypeHandler::type>"
45 | func = """
46 | static constexpr auto elementField = make_field("el");
47 |
48 | auto sum = std::get(d.val);
49 |
50 | el.container_stats = result::Element::ContainerStats {
51 | .capacity = 1,
52 | .length = sum.index,
53 | };
54 |
55 | if (sum.index == 1) {
56 | el.exclusive_size -= sizeof(T0);
57 | stack_ins(elementField);
58 | }
59 | """
60 |
--------------------------------------------------------------------------------
/oi/type_graph/Flattener.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 | #include
20 |
21 | #include "NodeTracker.h"
22 | #include "PassManager.h"
23 | #include "Types.h"
24 | #include "Visitor.h"
25 |
26 | namespace oi::detail::type_graph {
27 |
28 | /*
29 | * Flattener
30 | *
31 | * Flattens classes by removing parents and adding their attributes directly
32 | * into derived classes.
33 | */
34 | class Flattener : public RecursiveVisitor {
35 | public:
36 | static Pass createPass();
37 |
38 | Flattener(NodeTracker& tracker) : tracker_(tracker) {
39 | }
40 |
41 | using RecursiveVisitor::accept;
42 |
43 | void accept(Type& type) override;
44 | void visit(Class& c) override;
45 |
46 | static const inline std::string ParentPrefix = "__oi_parent";
47 |
48 | private:
49 | NodeTracker& tracker_;
50 | std::vector flattened_members_;
51 | std::vector offset_stack_;
52 | };
53 |
54 | } // namespace oi::detail::type_graph
55 |
--------------------------------------------------------------------------------
/cmake/StandardProjectSettings.cmake:
--------------------------------------------------------------------------------
1 | # Set a default build type if none was specified
2 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
3 | message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
4 | set(CMAKE_BUILD_TYPE
5 | RelWithDebInfo
6 | CACHE STRING "Choose the type of build." FORCE)
7 | # Set the possible values of build type for cmake-gui, ccmake
8 | set_property(
9 | CACHE CMAKE_BUILD_TYPE
10 | PROPERTY STRINGS
11 | "Debug"
12 | "Release"
13 | "MinSizeRel"
14 | "RelWithDebInfo")
15 | endif()
16 |
17 | # Generate compile_commands.json to make it easier to work with clang based tools
18 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
19 | # Include implicit directories in the compile commands file
20 | set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
21 |
22 | option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF)
23 |
24 | if(ENABLE_IPO)
25 | include(CheckIPOSupported)
26 | check_ipo_supported(
27 | RESULT
28 | result
29 | OUTPUT
30 | output)
31 | if(result)
32 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
33 | else()
34 | message(SEND_ERROR "IPO is not supported: ${output}")
35 | endif()
36 | endif()
37 | if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
38 | add_compile_options(-fcolor-diagnostics)
39 | elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
40 | add_compile_options(-fdiagnostics-color=auto)
41 | else()
42 | message(STATUS "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
43 | endif()
44 |
45 |
--------------------------------------------------------------------------------
/resources/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library(resources headers.cpp)
2 |
3 | target_include_directories(resources PRIVATE ../)
4 |
5 | function(embed_headers output)
6 | file(WRITE ${output} "#include \"oi/Headers.h\"\n\n")
7 | file(APPEND ${output} "namespace oi::detail::headers {\n")
8 |
9 | set(HEADERS
10 | ../include/oi/IntrospectionResult-inl.h
11 | ../include/oi/IntrospectionResult.h
12 | ../include/oi/exporters/ParsedData.h
13 | ../include/oi/exporters/inst.h
14 | ../include/oi/result/Element.h
15 | ../include/oi/types/dy.h
16 | ../include/oi/types/st.h
17 | ../oi/OITraceCode.cpp
18 | )
19 | foreach(header ${HEADERS})
20 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${header})
21 |
22 | file(REAL_PATH ${header} header_path)
23 | file(REAL_PATH ${CMAKE_SOURCE_DIR}/include include_path)
24 | file(REAL_PATH ${CMAKE_SOURCE_DIR} base_path)
25 |
26 | cmake_path(IS_PREFIX include_path ${header_path} NORMALIZE in_include)
27 | if (${in_include})
28 | file(RELATIVE_PATH header_rel_path ${include_path} ${header_path})
29 | else()
30 | file(RELATIVE_PATH header_rel_path ${base_path} ${header_path})
31 | endif()
32 |
33 | string(MAKE_C_IDENTIFIER ${header_rel_path} varname)
34 | get_filename_component(filename ${header} NAME)
35 |
36 | file(READ ${header} contents)
37 | file(APPEND ${output} "const std::string_view ${varname} = R\"CONTENTS(${contents})CONTENTS\";\n\n")
38 | endforeach()
39 |
40 | file(APPEND ${output} "} // namespace oi::detail::headers\n")
41 | endfunction()
42 |
43 | embed_headers(${CMAKE_BINARY_DIR}/resources/headers.cpp)
44 |
--------------------------------------------------------------------------------
/oi/OILexer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | /* It looks like the yyFlexLexerOnce method is not the correct way of doing
19 | this but it works for now. Fix it in the future. */
20 | #if !defined(yyFlexLexerOnce)
21 | #include
22 | #endif
23 |
24 | /* #pragma once
25 | #include */
26 |
27 | #include "OIParser.tab.hh"
28 | #include "location.hh"
29 |
30 | namespace oi::detail {
31 |
32 | class OIScanner : public yyFlexLexer {
33 | public:
34 | OIScanner(std::istream* in) : yyFlexLexer(in) {};
35 |
36 | virtual ~OIScanner() {};
37 |
38 | // get rid of override virtual function warning
39 | using FlexLexer::yylex;
40 |
41 | virtual int yylex(OIParser::semantic_type* const lval,
42 | OIParser::location_type* location);
43 | // YY_DECL defined in OILexer.l
44 | // Method body created by flex in OILexer.yy.cc
45 |
46 | private:
47 | /* yyval ptr */
48 | OIParser::semantic_type* yylval = nullptr;
49 | };
50 |
51 | } // namespace oi::detail
52 |
--------------------------------------------------------------------------------
/oi/type_graph/RemoveTopLevelPointer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #include "RemoveTopLevelPointer.h"
17 |
18 | #include "TypeGraph.h"
19 |
20 | namespace oi::detail::type_graph {
21 |
22 | Pass RemoveTopLevelPointer::createPass() {
23 | auto fn = [](TypeGraph& typeGraph, NodeTracker&) {
24 | RemoveTopLevelPointer pass;
25 | pass.removeTopLevelPointers(typeGraph.rootTypes());
26 | };
27 |
28 | return Pass("RemoveTopLevelPointer", fn);
29 | }
30 |
31 | void RemoveTopLevelPointer::removeTopLevelPointers(
32 | std::vector>& types) {
33 | for (size_t i = 0; i < types.size(); i++) {
34 | Type& type = types[i];
35 | topLevelType_ = &type;
36 | type.accept(*this);
37 | types[i] = *topLevelType_;
38 | }
39 | }
40 |
41 | void RemoveTopLevelPointer::visit(Pointer& p) {
42 | topLevelType_ = &p.pointeeType();
43 | }
44 |
45 | void RemoveTopLevelPointer::visit(Reference& r) {
46 | topLevelType_ = &r.pointeeType();
47 | }
48 |
49 | } // namespace oi::detail::type_graph
50 |
--------------------------------------------------------------------------------
/test/integration/std_multimap_custom_comparator.toml:
--------------------------------------------------------------------------------
1 | definitions = '''
2 | struct CustomComparator {
3 | bool operator()(const int& left, const int& right) const {
4 | return left < right;
5 | }
6 | };
7 |
8 | struct Foo {
9 | std::multimap m1;
10 | std::multimap m2;
11 | };
12 | '''
13 | includes = ["map"]
14 |
15 | [cases]
16 | [cases.a]
17 | param_types = ["const Foo&"]
18 | setup = '''
19 | Foo foo;
20 |
21 | for (int i = 0; i < 3; i++) {
22 | foo.m1.insert(std::pair(i,i));
23 | }
24 |
25 | for (int i = 0; i < 5; i++) {
26 | foo.m2.insert(std::pair(i,i));
27 | }
28 |
29 | return {foo};
30 | '''
31 | expect_json = '''[{
32 | "staticSize":96,
33 | "dynamicSize":76,
34 | "members":[
35 | {"name":"m1", "staticSize":48, "dynamicSize":36, "length":3, "capacity":3, "elementStaticSize":12},
36 | {"name":"m2", "staticSize":48, "dynamicSize":40, "length":5, "capacity":5, "elementStaticSize":8}
37 | ]}]'''
38 | expect_json_v2 = '''[{
39 | "staticSize":96,
40 | "exclusiveSize":0,
41 | "size":440,
42 | "members":[
43 | {"name":"m1",
44 | "staticSize":48,
45 | "exclusiveSize":48,
46 | "size":192,
47 | "length":3,
48 | "capacity":3,
49 | "members": [
50 | {"name":"[]", "staticSize":48, "exclusiveSize":36, "size":48},
51 | {},
52 | {}
53 | ]},
54 | {"name":"m2", "staticSize":48, "exclusiveSize":48, "size":248, "length":5, "capacity":5}
55 | ]}]'''
56 |
--------------------------------------------------------------------------------
/oi/type_graph/PassManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | namespace oi::detail::type_graph {
23 |
24 | class NodeTrackerHolder;
25 | class NodeTracker;
26 | class TypeGraph;
27 | class Type;
28 |
29 | /*
30 | * Pass
31 | *
32 | * TODO
33 | */
34 | class Pass {
35 | using PassFn =
36 | std::function;
37 |
38 | public:
39 | Pass(std::string name, PassFn fn) : name_(std::move(name)), fn_(fn) {
40 | }
41 | void run(TypeGraph& typeGraph, NodeTrackerHolder tracker);
42 | std::string& name() {
43 | return name_;
44 | };
45 |
46 | private:
47 | std::string name_;
48 | PassFn fn_;
49 | };
50 |
51 | /*
52 | * PassManager
53 | *
54 | * TODO
55 | */
56 | class PassManager {
57 | public:
58 | void addPass(Pass p);
59 | void run(TypeGraph& typeGraph);
60 |
61 | private:
62 | std::vector passes_;
63 | };
64 |
65 | } // namespace oi::detail::type_graph
66 |
--------------------------------------------------------------------------------
/test/integration/sorted_vector_set.toml:
--------------------------------------------------------------------------------
1 | includes = ["folly/sorted_vector_types.h"]
2 | definitions = '''
3 | using folly::sorted_vector_set;
4 | '''
5 |
6 | [cases]
7 | [cases.no_ints]
8 | param_types = ["const sorted_vector_set&"]
9 | setup = "return {};"
10 | expect_json = '''[{
11 | "staticSize":24,
12 | "dynamicSize":0,
13 | "length":0,
14 | "capacity":0,
15 | "elementStaticSize":4,
16 | "members":[{
17 | "staticSize": 24,
18 | "dynamicSize": 0,
19 | "length": 0,
20 | "capacity": 0,
21 | "elementStaticSize": 4
22 | }]}]'''
23 | expect_json_v2 = '''[{
24 | "staticSize": 24,
25 | "exclusiveSize": 24,
26 | "size": 24,
27 | "length": 0,
28 | "capacity": 0
29 | }]'''
30 |
31 | [cases.some_ints]
32 | param_types = ["const sorted_vector_set&"]
33 | setup = '''
34 | sorted_vector_set is;
35 | is.insert(1);
36 | is.insert(3);
37 | is.insert(2);
38 | is.insert(3);
39 | return is;
40 | '''
41 | expect_json = '''[{
42 | "staticSize": 24,
43 | "dynamicSize": 16,
44 | "exclusiveSize": 0,
45 | "length":3,
46 | "capacity":4,
47 | "elementStaticSize":4,
48 | "members": [{
49 | "staticSize": 24,
50 | "dynamicSize": 16,
51 | "exclusiveSize": 40,
52 | "length": 3,
53 | "capacity": 4,
54 | "elementStaticSize": 4
55 | }]}]
56 | '''
57 | expect_json_v2 = '''[{
58 | "staticSize": 24,
59 | "exclusiveSize": 28,
60 | "size": 40,
61 | "length": 3,
62 | "capacity": 4
63 | }]'''
64 |
--------------------------------------------------------------------------------
/test/test_drgn_parser.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "oi/type_graph/DrgnParser.h"
6 |
7 | namespace oi::detail {
8 | class SymbolService;
9 | }
10 | namespace oi::detail::type_graph {
11 | class TypeGraph;
12 | }
13 | struct drgn_type;
14 |
15 | using namespace oi::detail;
16 |
17 | class DrgnParserTest : public ::testing::Test {
18 | protected:
19 | static void SetUpTestSuite();
20 | static void TearDownTestSuite();
21 |
22 | static type_graph::DrgnParser getDrgnParser(
23 | type_graph::TypeGraph& typeGraph, type_graph::DrgnParserOptions options);
24 | drgn_type* getDrgnRoot(std::string_view function);
25 |
26 | virtual std::string run(std::string_view function,
27 | type_graph::DrgnParserOptions options);
28 | void test(std::string_view function,
29 | std::string_view expected,
30 | type_graph::DrgnParserOptions options);
31 | void test(std::string_view function, std::string_view expected);
32 | void testGlob(std::string_view function,
33 | std::string_view expected,
34 | type_graph::DrgnParserOptions options = {});
35 | void testMultiCompiler(std::string_view function,
36 | std::string_view expectedClang,
37 | std::string_view expectedGcc,
38 | type_graph::DrgnParserOptions options = {});
39 | void testMultiCompilerGlob(std::string_view function,
40 | std::string_view expectedClang,
41 | std::string_view expectedGcc,
42 | type_graph::DrgnParserOptions options = {});
43 |
44 | static SymbolService* symbols_;
45 | };
46 |
--------------------------------------------------------------------------------
/include/oi/result/Element.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #ifndef INCLUDED_OI_RESULT_ELEMENT_H
17 | #define INCLUDED_OI_RESULT_ELEMENT_H 1
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | namespace oi::result {
27 |
28 | struct Element {
29 | struct ContainerStats {
30 | size_t capacity;
31 | size_t length;
32 | };
33 | struct IsSetStats {
34 | bool is_set;
35 | };
36 | struct Pointer {
37 | uintptr_t p;
38 | };
39 | struct Scalar {
40 | uint64_t n;
41 | };
42 |
43 | std::string_view name;
44 | std::span type_path;
45 | std::span type_names;
46 | size_t static_size;
47 | size_t exclusive_size;
48 |
49 | std::optional pointer;
50 | std::variant data = {
51 | std::nullopt};
52 | std::optional container_stats;
53 | std::optional is_set_stats;
54 | bool is_primitive;
55 | };
56 |
57 | } // namespace oi::result
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/oi/type_graph/Prune.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #include "Prune.h"
17 |
18 | #include "TypeGraph.h"
19 | #include "TypeIdentifier.h"
20 |
21 | namespace oi::detail::type_graph {
22 |
23 | Pass Prune::createPass() {
24 | auto fn = [](TypeGraph& typeGraph, NodeTracker& tracker) {
25 | Prune pass{tracker};
26 | for (auto& type : typeGraph.rootTypes()) {
27 | pass.accept(type);
28 | }
29 | };
30 |
31 | return Pass("Prune", fn);
32 | }
33 |
34 | void Prune::accept(Type& type) {
35 | if (tracker_.visit(type))
36 | return;
37 |
38 | type.accept(*this);
39 | }
40 |
41 | void Prune::visit(Class& c) {
42 | RecursiveVisitor::visit(c);
43 |
44 | c.templateParams.clear();
45 | c.parents.clear();
46 | c.functions.clear();
47 |
48 | // Should we bother with this shrinking? It saves memory but costs CPU
49 | c.templateParams.shrink_to_fit();
50 | c.parents.shrink_to_fit();
51 | c.functions.shrink_to_fit();
52 | }
53 |
54 | void Prune::visit(Container& c) {
55 | RecursiveVisitor::visit(c);
56 |
57 | c.setUnderlying(nullptr);
58 | }
59 |
60 | } // namespace oi::detail::type_graph
61 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to GitHub Pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | # Review gh actions docs if you want to further define triggers, paths, etc
8 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
9 |
10 | jobs:
11 | deploy:
12 | defaults:
13 | run:
14 | working-directory: website
15 | name: Deploy to GitHub Pages
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/checkout@v3
19 | - uses: actions/setup-node@v3
20 | with:
21 | node-version: 18
22 | cache: yarn
23 | cache-dependency-path: ./website/yarn.lock
24 |
25 | - name: Install dependencies
26 | run: yarn install --frozen-lockfile
27 | - name: Build website
28 | run: yarn build
29 |
30 | # Popular action to deploy to GitHub Pages:
31 | # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
32 | - name: Deploy to GitHub Pages
33 | uses: peaceiris/actions-gh-pages@v3
34 | with:
35 | github_token: ${{ secrets.GITHUB_TOKEN }}
36 | # Build output to publish to the `gh-pages` branch:
37 | publish_dir: ./website/build
38 | # The following lines assign commit authorship to the official
39 | # GH-Actions bot for deploys to `gh-pages` branch:
40 | # https://github.com/actions/checkout/issues/13#issuecomment-724415212
41 | # The GH actions bot is used by default if you didn't specify the two fields.
42 | # You can swap them out with your own user credentials.
43 | user_name: github-actions[bot]
44 | user_email: 41898282+github-actions[bot]@users.noreply.github.com
45 |
--------------------------------------------------------------------------------
/.clang-tidy:
--------------------------------------------------------------------------------
1 | Checks: >
2 | -*,
3 | bugprone*,
4 | readability*,
5 | cppcoreguidelines*,
6 | clang-analyzer*,
7 | performance*,
8 | -cppcoreguidelines-pro-type-union-access,
9 | -cppcoreguidelines-pro-type-vararg,
10 | -cppcoreguidelines-avoid-non-const-global-variables,
11 | -cppcoreguidelines-pro-bounds-pointer-arithmetic,
12 | -readability-function-cognitive-complexity
13 |
14 | CheckOptions:
15 | - { key: readability-identifier-naming.NamespaceCase, value: lower_case }
16 | - { key: readability-identifier-naming.ClassCase, value: CamelCase }
17 | - { key: readability-identifier-naming.StructCase, value: CamelCase }
18 | - { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase }
19 | - { key: readability-identifier-naming.FunctionCase, value: camelBack }
20 | - { key: readability-identifier-naming.VariableCase, value: camelBack }
21 | - { key: readability-identifier-naming.ClassMemberCase, value: camelBack }
22 | - { key: readability-identifier-naming.ClassMemberCase, value: camelBack }
23 | - { key: readability-identifier-naming.PrivateMemberCase, value: camelBack }
24 | - { key: readability-identifier-naming.ProtectedMemberCase, value: camelBack }
25 | - { key: readability-identifier-naming.EnumConstantCase, value: camelBack }
26 | - { key: readability-identifier-naming.ConstexprVariableCase, value: camelBack }
27 | - { key: readability-identifier-naming.GlobalConstantCase, value: camelBack }
28 | - { key: readability-identifier-naming.MemberConstantCase, value: CamelCase }
29 | - { key: readability-identifier-naming.StaticConstantCase, value: camelBack }
30 | - { key: readability-implicit-bool-conversion.AllowIntegerConditions, value: 1 }
31 | - { key: readability-implicit-bool-conversion.AllowPointerConditions, value: 1 }
32 |
--------------------------------------------------------------------------------
/oi/type_graph/IdentifyContainers.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | #include "NodeTracker.h"
23 | #include "PassManager.h"
24 | #include "Types.h"
25 | #include "Visitor.h"
26 | #include "oi/ContainerInfo.h"
27 |
28 | namespace oi::detail::type_graph {
29 |
30 | class TypeGraph;
31 |
32 | /*
33 | * IdentifyContainers
34 | *
35 | * Walks a flattened type graph and replaces type nodes based on container
36 | * definition TOML files.
37 | */
38 | class IdentifyContainers : public RecursiveMutator {
39 | public:
40 | static Pass createPass(
41 | const std::vector>& containers);
42 |
43 | IdentifyContainers(
44 | TypeGraph& typeGraph,
45 | const std::vector>& containers);
46 |
47 | using RecursiveMutator::mutate;
48 |
49 | Type& mutate(Type& type) override;
50 | Type& visit(Class& c) override;
51 | Type& visit(Container& c) override;
52 |
53 | private:
54 | ResultTracker tracker_;
55 | TypeGraph& typeGraph_;
56 | const std::vector>& containers_;
57 | };
58 |
59 | } // namespace oi::detail::type_graph
60 |
--------------------------------------------------------------------------------
/types/string_type.toml:
--------------------------------------------------------------------------------
1 | [info]
2 | type_name = "std::basic_string"
3 | stub_template_params = [2]
4 | ctype = "STRING_TYPE"
5 | header = "string"
6 |
7 | # Old:
8 | typeName = "std::basic_string<"
9 | ns = ["namespace std"]
10 | numTemplateParams = 1
11 | replaceTemplateParamIndex = []
12 |
13 | [codegen]
14 | decl = """
15 | template
16 | void getSizeType(const %1% &container, size_t& returnArg);
17 | """
18 |
19 | func = """
20 | template
21 | void getSizeType(const %1% &container, size_t& returnArg)
22 | {
23 | SAVE_SIZE(sizeof(%1%));
24 |
25 | SAVE_DATA((uintptr_t)container.capacity());
26 | SAVE_DATA((uintptr_t)container.size());
27 |
28 | // Test for small string optimisation - whether the underlying string is
29 | // contained within the string object.
30 | SAVE_SIZE(
31 | isStorageInline(container) ? 0 : (container.capacity() * sizeof(T))
32 | );
33 | }
34 | """
35 |
36 | traversal_func = """
37 | bool sso = isStorageInline(container);
38 |
39 | return returnArg.write(container.capacity())
40 | .write(sso)
41 | .write(container.size());
42 | """
43 |
44 | [[codegen.processor]]
45 | type = "types::st::VarInt"
46 | func = """
47 | uint64_t capacity = std::get(d.val).value;
48 | el.container_stats.emplace(result::Element::ContainerStats { .capacity = capacity });
49 | """
50 |
51 | [[codegen.processor]]
52 | type = "types::st::VarInt"
53 | func = """
54 | bool sso = std::get(d.val).value;
55 | if (!sso)
56 | el.exclusive_size += el.container_stats->capacity * sizeof(T0);
57 | """
58 |
59 | [[codegen.processor]]
60 | type = "types::st::VarInt"
61 | func = """
62 | el.container_stats->length = std::get(d.val).value;
63 | """
64 |
--------------------------------------------------------------------------------
/oi/type_graph/RemoveMembers.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include
19 |
20 | #include "PassManager.h"
21 | #include "Types.h"
22 | #include "Visitor.h"
23 |
24 | namespace oi::detail::type_graph {
25 |
26 | /*
27 | * RemoveMembers
28 | *
29 | * Removes members as requested by the [[codegen.ignore]] section in the OI
30 | * config.
31 | *
32 | * Removes members from unions as we have no way of telling which one is active.
33 | */
34 | class RemoveMembers : public RecursiveVisitor {
35 | public:
36 | static Pass createPass(
37 | const std::vector>& membersToIgnore);
38 |
39 | RemoveMembers(
40 | const std::vector>& membersToIgnore)
41 | : membersToIgnore_(membersToIgnore) {
42 | }
43 |
44 | using RecursiveVisitor::accept;
45 |
46 | void accept(Type& type) override;
47 | void visit(Class& c) override;
48 |
49 | private:
50 | bool ignoreMember(std::string_view typeName,
51 | const std::string& memberName) const;
52 |
53 | std::unordered_set visited_;
54 | const std::vector>& membersToIgnore_;
55 | };
56 |
57 | } // namespace oi::detail::type_graph
58 |
--------------------------------------------------------------------------------
/types/ref_wrapper_type.toml:
--------------------------------------------------------------------------------
1 | [info]
2 | type_name = "std::reference_wrapper"
3 | ctype = "REF_WRAPPER_TYPE"
4 | header = "functional"
5 |
6 | # Old:
7 | typeName = "std::reference_wrapper<"
8 | ns = ["namespace std"]
9 | numTemplateParams = 1
10 | replaceTemplateParamIndex = []
11 |
12 | [codegen]
13 | decl = """
14 | template
15 | void getSizeType(const %1% &ref, size_t& returnArg);
16 | """
17 |
18 | func = """
19 | template
20 | void getSizeType(const %1% &ref, size_t& returnArg)
21 | {
22 | SAVE_SIZE(sizeof(%1%));
23 | SAVE_DATA((uintptr_t)&(ref.get()));
24 | if (ctx.pointers.add((uintptr_t)&ref.get())) {
25 | SAVE_DATA(1);
26 | getSizeType(ref.get(), returnArg);
27 | } else {
28 | SAVE_DATA(0);
29 | }
30 | }
31 | """
32 |
33 | traversal_func = """
34 | auto tail = returnArg.write((uintptr_t)&(container.get()));
35 |
36 | if (ctx.pointers.add((uintptr_t)&container.get())) {
37 | return tail.template delegate<1>([&ctx, &container](auto ret) {
38 | return OIInternal::getSizeType(ctx, container.get(), ret);
39 | });
40 | } else {
41 | return tail.template delegate<0>(std::identity());
42 | }
43 | """
44 |
45 | [[codegen.processor]]
46 | type = "types::st::VarInt"
47 | func = """
48 | el.pointer = std::get(d.val).value;
49 | """
50 |
51 | [[codegen.processor]]
52 | type = """
53 | types::st::Sum,
55 | typename TypeHandler::type>
56 | """
57 | func = """
58 | auto sum = std::get(d.val);
59 | el.container_stats.emplace(result::Element::ContainerStats {
60 | .capacity = 1,
61 | .length = sum.index, // 0 if in a cycle, 1 otherwise
62 | });
63 |
64 | if constexpr (oi_is_complete) {
65 | if (sum.index == 1) {
66 | static constexpr auto element = make_field("ref_val");
67 | stack_ins(element);
68 | }
69 | }
70 | """
71 |
--------------------------------------------------------------------------------
/oi/TypeHierarchy.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | #pragma once
17 |
18 | #include