diff options
author | Kyle Suarez <kyle.suarez@mongodb.com> | 2018-04-30 10:25:12 -0400 |
---|---|---|
committer | Kyle Suarez <kyle.suarez@mongodb.com> | 2018-04-30 11:14:59 -0400 |
commit | a9b53ada0db65e6ee341260c3256e960bac56a94 (patch) | |
tree | 17f359614f594c9427e982faa665578a05bd8728 /src/mongo/base | |
parent | 69b6d9846e3fae2fea9313757c7563b1061cf585 (diff) | |
download | mongo-a9b53ada0db65e6ee341260c3256e960bac56a94.tar.gz |
Revert "SERVER-32645 Create a shim helper framework."
This reverts commit 2227f272a7a0a3e43625cb2d4a2704e1ccb6f893.
Diffstat (limited to 'src/mongo/base')
-rw-r--r-- | src/mongo/base/init.h | 8 | ||||
-rw-r--r-- | src/mongo/base/shim.cpp | 36 | ||||
-rw-r--r-- | src/mongo/base/shim.h | 256 |
3 files changed, 4 insertions, 296 deletions
diff --git a/src/mongo/base/init.h b/src/mongo/base/init.h index 50a8eee3529..1d6595592aa 100644 --- a/src/mongo/base/init.h +++ b/src/mongo/base/init.h @@ -117,15 +117,15 @@ * of the function to declare would be options. */ #define MONGO_INITIALIZER_GENERAL(NAME, PREREQUISITES, DEPENDENTS) \ - ::mongo::Status MONGO_INITIALIZER_FUNCTION_NAME_(NAME)(::mongo::InitializerContext*); \ + ::mongo::Status _MONGO_INITIALIZER_FUNCTION_NAME(NAME)(::mongo::InitializerContext*); \ namespace { \ ::mongo::GlobalInitializerRegisterer _mongoInitializerRegisterer_##NAME( \ std::string(#NAME), \ MONGO_MAKE_STRING_VECTOR PREREQUISITES, \ MONGO_MAKE_STRING_VECTOR DEPENDENTS, \ - mongo::InitializerFunction(MONGO_INITIALIZER_FUNCTION_NAME_(NAME))); \ + mongo::InitializerFunction(_MONGO_INITIALIZER_FUNCTION_NAME(NAME))); \ } \ - ::mongo::Status MONGO_INITIALIZER_FUNCTION_NAME_(NAME) + ::mongo::Status _MONGO_INITIALIZER_FUNCTION_NAME(NAME) /** * Macro to define an initializer group. @@ -143,4 +143,4 @@ * Macro to produce a name for a mongo initializer function for an initializer operation * named "NAME". */ -#define MONGO_INITIALIZER_FUNCTION_NAME_(NAME) _mongoInitializerFunction_##NAME +#define _MONGO_INITIALIZER_FUNCTION_NAME(NAME) _mongoInitializerFunction_##NAME diff --git a/src/mongo/base/shim.cpp b/src/mongo/base/shim.cpp deleted file mode 100644 index b5834086563..00000000000 --- a/src/mongo/base/shim.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (C) 2018 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#include "mongo/base/shim.h" - - -namespace mongo { -namespace { -MONGO_INITIALIZER_GROUP(ShimHooks, MONGO_NO_PREREQUISITES, ("default")); -} // namespace -} // namespace mongo diff --git a/src/mongo/base/shim.h b/src/mongo/base/shim.h deleted file mode 100644 index 28437322b8b..00000000000 --- a/src/mongo/base/shim.h +++ /dev/null @@ -1,256 +0,0 @@ -/** - * Copyright (C) 2018 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#pragma once - -#include <functional> - -#include "mongo/base/init.h" - -/** - * The `SHIM` mechanism allows for the creation of "weak-symbol-like" functions which can have their - * actual implementation injected in the final binary without creating a link dependency upon any - * actual implementation. One uses it like this: - * - * In a header: - * ``` - * class MyClass { - * public: - * static MONGO_DECLARE_SHIM((int)->std::string) helloWorldFunction; - * }; - * ``` - * - * In the corresponding C++ file (which is a link dependency): - * ``` - * MONGO_DEFINE_SHIM(MyClass::helloWorldFunction); - * ``` - * - * And in any number of implementation files: - * ``` - * MONGO_REGISTER_SHIM(MyClass::helloWorldFunction)(int value)->std::string { - * if (value == 42) { - * return "Hello World"; - * } else { - * return "No way!"; - * } - * } - * ``` - * - * This can be useful for making auto-registering and auto-constructing mock and release class - * factories, among other useful things - */ - -namespace mongo { -template <typename T> -struct PrivateCall; - -/** - * When declaring shim functions that should be private, they really need to be public; however, - * this type can be used as a parameter to permit the function to only be called by the type - * specified in the template parameter. - */ -template <typename T> -struct PrivateTo { -private: - friend PrivateCall<T>; - - PrivateTo() = default; -}; - -/** - * When calling shim functions that should be private, you pass an immediately created instance of - * the type `PrivateCall< T >`, where `T` is the type that `PrivateTo` requires as a template - * parameter. - */ -template <typename T> -struct PrivateCall { -private: - friend T; - PrivateCall() {} - -public: - operator PrivateTo<T>() { - return {}; - } -}; -} // namespace mongo - -namespace shim_detail { -/** - * This type, `storage`, is used as a workaround for needing C++17 `inline` variables. The template - * static member is effectively `inline` already. - */ -template <typename T, typename tag = void> -struct storage { - static T data; -}; - -template <typename T, typename tag> -T storage<T, tag>::data = {}; -} // namespace shim_detail - -#define MONGO_SHIM_DEPENDENTS ("ShimHooks") - -namespace mongo { -#ifdef MONGO_CONFIG_CHECK_SHIM_DEPENDENCIES -const bool checkShimsViaTUHook = true; -#define MONGO_SHIM_TU_HOOK(name) \ - name {} -#else -const bool checkShimsViaTUHook = false; -#define MONGO_SHIM_TU_HOOK(name) -#endif -} // namespace mongo - -/** - * Declare a shimmable function with signature `SHIM_SIGNATURE`. Declare such constructs in a C++ - * header as static members of a class. - */ -#define MONGO_DECLARE_SHIM(/*SHIM_SIGNATURE*/...) MONGO_DECLARE_SHIM_1(__LINE__, __VA_ARGS__) -#define MONGO_DECLARE_SHIM_1(LN, ...) MONGO_DECLARE_SHIM_2(LN, __VA_ARGS__) -#define MONGO_DECLARE_SHIM_2(LN, ...) \ - const struct ShimBasis_##LN { \ - ShimBasis_##LN() = default; \ - struct MongoShimImplGuts { \ - template <bool required = mongo::checkShimsViaTUHook> \ - struct AbiCheckType { \ - AbiCheckType() = default; \ - }; \ - using AbiCheck = AbiCheckType<>; \ - struct LibTUHookTypeBase { \ - LibTUHookTypeBase(); \ - }; \ - template <bool required = mongo::checkShimsViaTUHook> \ - struct LibTUHookType : LibTUHookTypeBase {}; \ - using LibTUHook = LibTUHookType<>; \ - struct ImplTUHookTypeBase { \ - ImplTUHookTypeBase(); \ - }; \ - template <bool required = mongo::checkShimsViaTUHook> \ - struct ImplTUHookType : ImplTUHookTypeBase {}; \ - using ImplTUHook = ImplTUHookType<>; \ - \ - static auto functionTypeHelper __VA_ARGS__; \ - /* Workaround for Microsoft -- by taking the address of this function pointer, we \ - * avoid the problems that their compiler has with default * arguments in deduced \ - * typedefs. */ \ - using function_type_pointer = decltype(&MongoShimImplGuts::functionTypeHelper); \ - using function_type = std::remove_pointer_t<function_type_pointer>; \ - MongoShimImplGuts* abi(const AbiCheck* const) { \ - return this; \ - } \ - MongoShimImplGuts* lib(const LibTUHook* const) { \ - MONGO_SHIM_TU_HOOK(LibTUHook); \ - return this; \ - } \ - MongoShimImplGuts* impl(const ImplTUHook* const) { \ - MONGO_SHIM_TU_HOOK(ImplTUHook); \ - return this; \ - } \ - virtual auto implementation __VA_ARGS__ = 0; \ - \ - using tag = \ - std::tuple<MongoShimImplGuts::function_type, AbiCheck, LibTUHook, ImplTUHook>; \ - }; \ - \ - using storage = shim_detail::storage<MongoShimImplGuts*, MongoShimImplGuts::tag>; \ - \ - /* TODO: When the dependency graph is fixed, add the `impl()->` call to the call chain */ \ - template <typename... Args> \ - auto operator()(Args&&... args) const \ - noexcept(noexcept(storage::data->abi(nullptr)->lib(nullptr)->implementation( \ - std::forward<Args>(args)...))) \ - -> decltype(storage::data->abi(nullptr)->lib(nullptr)->implementation( \ - std::forward<Args>(args)...)) { \ - return storage::data->abi(nullptr)->lib(nullptr)->implementation( \ - std::forward<Args>(args)...); \ - } \ - } - -/** - * Define a shimmable function with name `SHIM_NAME`, returning a value of type `RETURN_TYPE`, with - * any arguments. This shim definition macro should go in the associated C++ file to the header - * where a SHIM was defined. This macro does not emit a function definition, only the customization - * point's machinery. - */ -#define MONGO_DEFINE_SHIM(/*SHIM_NAME*/...) MONGO_DEFINE_SHIM_1(__LINE__, __VA_ARGS__) -#define MONGO_DEFINE_SHIM_1(LN, ...) MONGO_DEFINE_SHIM_2(LN, __VA_ARGS__) -#define MONGO_DEFINE_SHIM_2(LN, ...) \ - namespace { \ - namespace shim_namespace##LN { \ - using ShimType = decltype(__VA_ARGS__); \ - } /*namespace shim_namespace*/ \ - } /*namespace*/ \ - shim_namespace##LN::ShimType::MongoShimImplGuts::LibTUHookTypeBase::LibTUHookTypeBase() = \ - default; \ - shim_namespace##LN::ShimType __VA_ARGS__{}; - -#define MONGO_SHIM_EVIL_STRINGIFY_(args) #args - - -/** - * Define an implementation of a shimmable function with name `SHIM_NAME`. The compiler will check - * supplied parameters for correctness. This shim registration macro should go in the associated - * C++ implementation file to the header where a SHIM was defined. Such a file would be a mock - * implementation or a real implementation, for example - */ -#define MONGO_REGISTER_SHIM(/*SHIM_NAME*/...) MONGO_REGISTER_SHIM_1(__LINE__, __VA_ARGS__) -#define MONGO_REGISTER_SHIM_1(LN, ...) MONGO_REGISTER_SHIM_2(LN, __VA_ARGS__) -#define MONGO_REGISTER_SHIM_2(LN, ...) \ - namespace { \ - namespace shim_namespace##LN { \ - using ShimType = decltype(__VA_ARGS__); \ - \ - class Implementation final : public ShimType::MongoShimImplGuts { \ - /* Some compilers don't work well with the trailing `override` in this kind of \ - * function declaration. */ \ - ShimType::MongoShimImplGuts::function_type implementation; /* override */ \ - }; \ - \ - ::mongo::Status createInitializerRegistration(::mongo::InitializerContext* const) { \ - static Implementation impl; \ - ShimType::storage::data = &impl; \ - return Status::OK(); \ - } \ - \ - const ::mongo::GlobalInitializerRegisterer registrationHook{ \ - std::string(MONGO_SHIM_EVIL_STRINGIFY_((__VA_ARGS__))), \ - {}, \ - {MONGO_SHIM_DEPENDENTS}, \ - mongo::InitializerFunction(createInitializerRegistration)}; \ - } /*namespace shim_namespace*/ \ - } /*namespace*/ \ - \ - shim_namespace##LN::ShimType::MongoShimImplGuts::ImplTUHookTypeBase::ImplTUHookTypeBase() = \ - default; \ - \ - auto shim_namespace##LN::Implementation::implementation /* After this point someone just \ - writes the signature's arguments \ - and return value (using arrow \ - notation). Then they write the \ - body. */ |