From 138c66fd8bdb352135347ac96c37578ddc255584 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Wed, 19 May 2021 11:55:39 +0200 Subject: [PATCH 1/7] [cling] Make sure required symbols are exported: and use a standard mechanism that plays well with -fvisibility. Given that several symbols now use declspec(dllexport), remove them from the ad-hoc cling_exports in ROOT's CMakeLists.txt. --- core/clingutils/CMakeLists.txt | 4 +- core/metacling/src/CMakeLists.txt | 60 ------------------- .../include/cling/Interpreter/CValuePrinter.h | 4 ++ .../DynamicLookupRuntimeUniverse.h | 2 + .../cling/Interpreter/RuntimePrintValue.h | 35 ++++++++++- .../cling/Interpreter/RuntimeUniverse.h | 10 +++- .../cling/include/cling/Interpreter/Value.h | 4 +- .../include/cling/Interpreter/Visibility.h | 33 ++++++++++ .../include/cling/module.modulemap.build | 1 + .../cling/lib/Interpreter/Exception.cpp | 2 + .../cling/lib/Interpreter/Interpreter.cpp | 2 + .../ValueExtractionSynthesizer.cpp | 14 +++++ .../cling/lib/Interpreter/ValuePrinter.cpp | 40 ++++++++++++- 13 files changed, 144 insertions(+), 67 deletions(-) create mode 100644 interpreter/cling/include/cling/Interpreter/Visibility.h diff --git a/core/clingutils/CMakeLists.txt b/core/clingutils/CMakeLists.txt index c243017e026f2..a50dca214f6a2 100644 --- a/core/clingutils/CMakeLists.txt +++ b/core/clingutils/CMakeLists.txt @@ -134,7 +134,9 @@ foreach(file ${custom_modulemaps} Interpreter/RuntimePrintValue.h Interpreter/RuntimeUniverse.h Interpreter/RuntimeOptions.h - Interpreter/Value.h) + Interpreter/Value.h + Interpreter/Visibility.h + ) get_filename_component(path ${file} PATH) set(dest_file ${file}) if (${file} STREQUAL "module.modulemap.build") diff --git a/core/metacling/src/CMakeLists.txt b/core/metacling/src/CMakeLists.txt index 41e8beaf902ec..d571e9561ad98 100644 --- a/core/metacling/src/CMakeLists.txt +++ b/core/metacling/src/CMakeLists.txt @@ -124,7 +124,6 @@ if(MSVC) ) if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64") set(cling_exports ${cling_exports} - ??1Value@cling@@QEAA@XZ ??2@YAPEAX_K@Z ??2@YAPEAX_KPEAX@Z ??2@YAPEAX_KHPEBDH@Z @@ -136,7 +135,6 @@ if(MSVC) ??_V@YAXPEAX@Z ??_V@YAXPEAX_K@Z ??_V@YAXPEAXHPEBDH@Z - ?kEmptyCollection@valuePrinterInternal@cling@@3QEBDEB ?print@Decl@clang@@QEBAXAEAVraw_ostream@llvm@@I_N@Z ??6raw_ostream@llvm@@QEAAAEAV01@PEBX@Z ?decls_begin@DeclContext@clang@@QEBA?AVdecl_iterator@12@XZ @@ -162,42 +160,6 @@ if(MSVC) ??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@D@Z ??$?6U?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@PEBD@Z ??$endl@DU?$char_traits@D@std@@@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPEAX00D@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPEAX00DM@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPEAX00DN@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPEAX00DO@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPEAX00D_K@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPEAX00DPEBX@Z - ?setValueWithAlloc@internal@runtime@cling@@YAPEAXPEAX00D@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEAPEBD@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEAPEBX@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBC@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBD@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBE@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBF@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBG@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBH@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBI@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBJ@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBK@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBM@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBN@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBO@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBQEBD@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBV23@@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBV?$basic_string@_SU?$char_traits@_S@std@@V?$allocator@_S@2@@3@@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBV?$basic_string@_UU?$char_traits@_U@std@@V?$allocator@_U@2@@3@@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@3@@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBVValue@1@@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBX@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEB_J@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEB_K@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEB_N@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEB_S@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEB_U@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEB_W@Z - ??$toUTF8@D@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBD_KD@Z - ?EvaluateDynamicExpression@internal@runtime@cling@@YA?AVValue@3@PEAVInterpreter@3@PEAVDynamicExprInfo@123@PEAVDeclContext@clang@@@Z ) if($) set(cling_exports ${cling_exports} ??$dyn_cast@VValueDecl@clang@@$$CBVDecl@2@@llvm@@YAPEBVValueDecl@clang@@PEBVDecl@2@@Z) @@ -219,28 +181,6 @@ if(MSVC) ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ??$endl@DU?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@@Z ?_Facet_Register@std@@YAXPAV_Facet_base@1@@Z - ??1Value@cling@@QAE@XZ - ?isValid@Value@cling@@QBE_NXZ - ?kEmptyCollection@valuePrinterInternal@cling@@3QBDB - ?AssertOnUnsupportedTypeCast@Value@cling@@IBEXXZ - ?setValueNoAlloc@internal@runtime@cling@@YAXPAX00D@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPAX00DM@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPAX00DN@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPAX00DO@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPAX00D_K@Z - ?setValueNoAlloc@internal@runtime@cling@@YAXPAX00DPBX@Z - ?setValueWithAlloc@internal@runtime@cling@@YAPAXPAX00D@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBI@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBM@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBN@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBH@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBX@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PB_N@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAPBX@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAPBD@Z - ?printValue@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBV23@@Z - ??$toUTF8@D@cling@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBDID@Z - ?EvaluateDynamicExpression@internal@runtime@cling@@YA?AVValue@3@PAVInterpreter@3@PAVDynamicExprInfo@123@PAVDeclContext@clang@@@Z ) if(MSVC_VERSION LESS 1914) set(cling_exports ${cling_exports} ??3@YAXPAX0@Z ??_V@YAXPAX0@Z) diff --git a/interpreter/cling/include/cling/Interpreter/CValuePrinter.h b/interpreter/cling/include/cling/Interpreter/CValuePrinter.h index a3b71a79bf70f..e5bf24717ac86 100644 --- a/interpreter/cling/include/cling/Interpreter/CValuePrinter.h +++ b/interpreter/cling/include/cling/Interpreter/CValuePrinter.h @@ -9,9 +9,13 @@ #ifndef CLING_VALUEPRINTERC_H #define CLING_VALUEPRINTERC_H + +#include + #ifdef __cplusplus extern "C" #endif +CLING_LIB_EXPORT void cling_PrintValue(void* /*cling::Value**/ V); #endif // CLING_VALUEPRINTERC_H diff --git a/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h b/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h index c7ec07226261c..35502757540d7 100644 --- a/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h +++ b/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h @@ -16,6 +16,7 @@ #include "cling/Interpreter/DynamicExprInfo.h" #include "cling/Interpreter/DynamicLookupLifetimeHandler.h" #include "cling/Interpreter/Value.h" +#include "cling/Interpreter/Visibility.h" namespace cling { @@ -28,6 +29,7 @@ namespace runtime { namespace internal { /// \brief Outlined Evaluate() implementation to not include Interpreter.h /// into the runtime. + CLING_LIB_EXPORT Value EvaluateDynamicExpression(Interpreter* interp, DynamicExprInfo* DEI, clang::DeclContext* DC); diff --git a/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h b/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h index 3111720f17eef..0924b94024879 100644 --- a/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h +++ b/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h @@ -14,6 +14,8 @@ #error "This file must not be included by compiled programs." #endif +#include + #include #include #include @@ -24,6 +26,7 @@ namespace cling { class Value; // General fallback - prints the address + CLING_LIB_EXPORT std::string printValue(const void *ptr); // Fallback for e.g. vector's bit iterator: @@ -32,64 +35,90 @@ namespace cling { inline std::string printValue(const T& val) { return "{not representable}"; } // void pointer + CLING_LIB_EXPORT std::string printValue(const void **ptr); // Bool + CLING_LIB_EXPORT std::string printValue(const bool *val); // Chars + CLING_LIB_EXPORT std::string printValue(const char *val); + CLING_LIB_EXPORT std::string printValue(const signed char *val); + CLING_LIB_EXPORT std::string printValue(const unsigned char *val); + CLING_LIB_EXPORT std::string printValue(const char16_t *val); + CLING_LIB_EXPORT std::string printValue(const char32_t *val); + CLING_LIB_EXPORT std::string printValue(const wchar_t *val); // Ints + CLING_LIB_EXPORT std::string printValue(const short *val); + CLING_LIB_EXPORT std::string printValue(const unsigned short *val); + CLING_LIB_EXPORT std::string printValue(const int *val); + CLING_LIB_EXPORT std::string printValue(const unsigned int *val); + CLING_LIB_EXPORT std::string printValue(const long *val); + CLING_LIB_EXPORT std::string printValue(const unsigned long *val); + CLING_LIB_EXPORT std::string printValue(const long long *val); + CLING_LIB_EXPORT std::string printValue(const unsigned long long *val); // Reals + CLING_LIB_EXPORT std::string printValue(const float *val); + CLING_LIB_EXPORT std::string printValue(const double *val); + CLING_LIB_EXPORT std::string printValue(const long double *val); // Char pointers + CLING_LIB_EXPORT std::string printValue(const char *const *val); + CLING_LIB_EXPORT std::string printValue(const char **val); // std::string + CLING_LIB_EXPORT std::string printValue(const std::string *val); + CLING_LIB_EXPORT std::string printValue(const std::wstring *val); + CLING_LIB_EXPORT std::string printValue(const std::u16string *val); + CLING_LIB_EXPORT std::string printValue(const std::u32string *val); // constant unicode strings, i.e. u"String" template + CLING_LIB_EXPORT std::string toUTF8(const T* const Src, size_t N, const char Prefix = 0); template @@ -113,9 +142,11 @@ namespace cling { } // cling::Value + CLING_LIB_EXPORT std::string printValue(const Value *value); namespace valuePrinterInternal { + CLING_LIB_EXPORT extern const char* const kEmptyCollection; } @@ -123,7 +154,9 @@ namespace cling { namespace collectionPrinterInternal { // Forward declaration, so recursion of containers possible. - template std::string printValue(const T* V, const void* = 0); + template + CLING_LIB_EXPORT + std::string printValue(const T* V, const void* = 0); template inline std::string printValue(const T& V, typename std::enable_if< diff --git a/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h b/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h index a105b19fad26a..58fb70cc49e7e 100644 --- a/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h +++ b/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h @@ -24,6 +24,7 @@ #ifdef __cplusplus #include +#include "cling/Interpreter/Visibility.h" #include namespace cling { @@ -58,6 +59,7 @@ namespace cling { ///\param [in] vpT - The opaque ptr for the cling::Transaction. ///\param [out] vpSVR - The Value that is created. /// + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn); ///\brief Set the value of the GenericValue for the expression @@ -69,6 +71,7 @@ namespace cling { ///\param [in] vpT - The opaque ptr for the cling::Transaction. ///\param [out] vpSVR - The Value that is created. /// + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, char vpOn, float value); @@ -81,6 +84,7 @@ namespace cling { ///\param [in] vpT - The opaque ptr for the cling::Transaction. ///\param [out] vpSVR - The Value that is created. /// + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, char vpOn, double value); @@ -94,6 +98,7 @@ namespace cling { ///\param [in] vpT - The opaque ptr for the cling::Transaction. ///\param [out] vpSVR - The Value that is created. /// + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, char vpOn, long double value); @@ -108,6 +113,7 @@ namespace cling { ///\param [in] vpT - The opaque ptr for the cling::Transaction. ///\param [out] vpSVR - The Value that is created. /// + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, char vpOn, unsigned long long value); @@ -120,6 +126,7 @@ namespace cling { ///\param [in] vpT - The opaque ptr for the cling::Transaction. ///\param [out] vpV - The Value that is created. /// + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, char vpOn, const void* value); @@ -132,6 +139,7 @@ namespace cling { /// ///\returns the address where the value should be put. /// + CLING_LIB_EXPORT void* setValueWithAlloc(void* vpI, void* vpV, void* vpQT, char vpOn); ///\brief Placement new doesn't work for arrays. It needs to be called on @@ -185,7 +193,7 @@ extern "C" { /// the definition of the exceptions from the RuntimeUniverse and allows us to /// run cling in -no-rtti mode. /// - + CLING_LIB_EXPORT void* cling_runtime_internal_throwIfInvalidPointer(void* Sema, void* Expr, const void* Arg); diff --git a/interpreter/cling/include/cling/Interpreter/Value.h b/interpreter/cling/include/cling/Interpreter/Value.h index 4a8f7be54f524..829b89ddf33b9 100644 --- a/interpreter/cling/include/cling/Interpreter/Value.h +++ b/interpreter/cling/include/cling/Interpreter/Value.h @@ -10,6 +10,8 @@ #ifndef CLING_VALUE_H #define CLING_VALUE_H +#include "cling/Interpreter/Visibility.h" + #include #include #include @@ -37,7 +39,7 @@ namespace cling { /// clang::QualType. Use-cases are expression evaluation, value printing /// and parameters for function calls. /// - class Value { + class CLING_LIB_EXPORT Value { protected: ///\brief Multi-purpose storage. /// diff --git a/interpreter/cling/include/cling/Interpreter/Visibility.h b/interpreter/cling/include/cling/Interpreter/Visibility.h new file mode 100644 index 0000000000000..7eb04237fc9ad --- /dev/null +++ b/interpreter/cling/include/cling/Interpreter/Visibility.h @@ -0,0 +1,33 @@ +//------------------------------------------------------------------------------ +// CLING - the C++ LLVM-based InterpreterG :) +// author: Axel Naumann +// +// This file is dual-licensed: you can choose to license it under the University +// of Illinois Open Source License or the GNU Lesser General Public License. See +// LICENSE.TXT for details. +//------------------------------------------------------------------------------ + +#ifndef CLING_VISIBILITY_H +#define CLING_VISIBILITY_H + +#include + +// Adapted from llvm/Support/Compiler.h +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) +// Adapted from https://gcc.gnu.org/wiki/Visibility +# ifdef __GNUC__ +# define CLING_LIB_EXPORT __attribute__ ((dllexport)) +# else +# define CLING_LIB_EXPORT __declspec(dllexport) +# endif +#elif (__has_attribute(visibility)) +# define CLING_LIB_EXPORT __attribute__ ((visibility("default"))) +#else +# define CLING_LIB_EXPORT +#endif + +#endif // CLING_VISIBILITY_H diff --git a/interpreter/cling/include/cling/module.modulemap.build b/interpreter/cling/include/cling/module.modulemap.build index f49d7e381f195..55ed9291a340e 100644 --- a/interpreter/cling/include/cling/module.modulemap.build +++ b/interpreter/cling/include/cling/module.modulemap.build @@ -12,5 +12,6 @@ module Cling_Runtime_Extra { module "DynamicExprInfo.h" { header "Interpreter/DynamicExprInfo.h" export * } module "DynamicLookupLifetimeHandler.h" { header "Interpreter/DynamicLookupLifetimeHandler.h" export * } module "Value.h" { header "Interpreter/Value.h" export * } + module "Visibility.h" { header "Interpreter/Visibility.h" export * } export * } diff --git a/interpreter/cling/lib/Interpreter/Exception.cpp b/interpreter/cling/lib/Interpreter/Exception.cpp index 6a7748ba7e02f..ffa0c3e3a45b9 100644 --- a/interpreter/cling/lib/Interpreter/Exception.cpp +++ b/interpreter/cling/lib/Interpreter/Exception.cpp @@ -12,6 +12,7 @@ #include "cling/Interpreter/InterpreterCallbacks.h" #include "cling/Interpreter/Interpreter.h" +#include "cling/Interpreter/Visibility.h" #include "cling/Utils/Validation.h" #include "clang/Frontend/CompilerInstance.h" @@ -27,6 +28,7 @@ extern "C" { ///\returns void*, const-cast from Arg, to reduce the complexity in the /// calling AST nodes, at the expense of possibly doing a /// T* -> const void* -> const_cast -> T* round trip. +CLING_LIB_EXPORT void* cling_runtime_internal_throwIfInvalidPointer(void* Interp, void* Expr, const void* Arg) { diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp index fe2b4c472ecac..c512a94f36d75 100644 --- a/interpreter/cling/lib/Interpreter/Interpreter.cpp +++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp @@ -35,6 +35,7 @@ #include "cling/Interpreter/LookupHelper.h" #include "cling/Interpreter/Transaction.h" #include "cling/Interpreter/Value.h" +#include "cling/Interpreter/Visibility.h" #include "cling/Utils/AST.h" #include "cling/Utils/Casting.h" #include "cling/Utils/Output.h" @@ -1818,6 +1819,7 @@ namespace cling { namespace runtime { namespace internal { + CLING_LIB_EXPORT Value EvaluateDynamicExpression(Interpreter* interp, DynamicExprInfo* DEI, clang::DeclContext* DC) { Value ret = [&] diff --git a/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp b/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp index 544ed8274a1dd..fc5685722a25d 100644 --- a/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp +++ b/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp @@ -12,6 +12,7 @@ #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/Transaction.h" #include "cling/Interpreter/Value.h" +#include "cling/Interpreter/Visibility.h" #include "cling/Utils/AST.h" #include "clang/AST/ASTContext.h" @@ -513,38 +514,51 @@ namespace { namespace cling { namespace runtime { namespace internal { + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn) { // In cases of void we 'just' need to change the type of the value. allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT); } + + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn, float value) { allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT).getAs() = value; dumpIfNoStorage(vpSVR, vpOn); } + + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn, double value) { allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT).getAs() = value; dumpIfNoStorage(vpSVR, vpOn); } + + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn, long double value) { allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT).getAs() = value; dumpIfNoStorage(vpSVR, vpOn); } + + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn, unsigned long long value) { allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT) .getAs() = value; dumpIfNoStorage(vpSVR, vpOn); } + + CLING_LIB_EXPORT void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn, const void* value){ allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT).getAs() = const_cast(value); dumpIfNoStorage(vpSVR, vpOn); } + + CLING_LIB_EXPORT void* setValueWithAlloc(void* vpI, void* vpSVR, void* vpQT, char vpOn) { return allocateStoredRefValueAndGetGV(vpI, vpSVR, vpQT).getAs(); } diff --git a/interpreter/cling/lib/Interpreter/ValuePrinter.cpp b/interpreter/cling/lib/Interpreter/ValuePrinter.cpp index 1d8ecd96c7f16..4bfe973ab5d60 100644 --- a/interpreter/cling/lib/Interpreter/ValuePrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ValuePrinter.cpp @@ -16,6 +16,7 @@ #include "cling/Interpreter/LookupHelper.h" #include "cling/Interpreter/Transaction.h" #include "cling/Interpreter/Value.h" +#include "cling/Interpreter/Visibility.h" #include "cling/Utils/AST.h" #include "cling/Utils/Casting.h" #include "cling/Utils/Output.h" @@ -53,7 +54,8 @@ using namespace cling; // Implements the CValuePrinter interface. -extern "C" void cling_PrintValue(void * /*cling::Value* V*/) { +extern "C" CLING_LIB_EXPORT +void cling_PrintValue(void * /*cling::Value* V*/) { //Value* value = (Value*)V; //std::string typeStr = printTypeInternal(*value); @@ -63,6 +65,7 @@ extern "C" void cling_PrintValue(void * /*cling::Value* V*/) { // Exported for RuntimePrintValue.h namespace cling { namespace valuePrinterInternal { + CLING_LIB_EXPORT extern const char* const kEmptyCollection = "{}"; struct OpaqueString{}; @@ -176,18 +179,20 @@ static std::string printAddress(const void* Ptr, const char Prfx = 0) { } // anonymous namespace namespace cling { - // General fallback - prints the address + CLING_LIB_EXPORT std::string printValue(const void *ptr) { return printAddress(ptr, '@'); } // void pointer + CLING_LIB_EXPORT std::string printValue(const void **ptr) { return printAddress(*ptr); } // Bool + CLING_LIB_EXPORT std::string printValue(const bool *val) { return *val ? kTrueStr : kFalseStr; } @@ -215,61 +220,72 @@ namespace cling { return Strm.str(); } + CLING_LIB_EXPORT std::string printValue(const char *val) { return printOneChar(*val); } + CLING_LIB_EXPORT std::string printValue(const signed char *val) { return printOneChar(*val); } + CLING_LIB_EXPORT std::string printValue(const unsigned char *val) { return printOneChar(*val); } // Ints + CLING_LIB_EXPORT std::string printValue(const short *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const unsigned short *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const int *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const unsigned int *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const long *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const unsigned long *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const long long *val) { cling::smallstream strm; strm << *val; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const unsigned long long *val) { cling::smallstream strm; strm << *val; @@ -277,18 +293,21 @@ namespace cling { } // Reals + CLING_LIB_EXPORT std::string printValue(const float *val) { cling::smallstream strm; strm << llvm::format("%#.6g", *val) << 'f'; return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const double *val) { cling::smallstream strm; strm << llvm::format("%#.8g", *val); return strm.str(); } + CLING_LIB_EXPORT std::string printValue(const long double *val) { cling::smallstream strm; strm << llvm::format("%#.8Lg", *val) << 'L'; @@ -297,7 +316,7 @@ namespace cling { } // Char pointers - std::string printString(const char *const *Ptr, size_t N = 10000) { + static std::string printString(const char *const *Ptr, size_t N = 10000) { // Assumption is this is a string. // N is limit to prevent endless loop if Ptr is not really a string. @@ -338,15 +357,18 @@ namespace cling { return Strm.str(); } + CLING_LIB_EXPORT std::string printValue(const char *const *val) { return printString(val); } + CLING_LIB_EXPORT std::string printValue(const char **val) { return printString(val); } // std::string + CLING_LIB_EXPORT std::string printValue(const std::string *val) { return "\"" + *val + "\""; } @@ -460,21 +482,25 @@ namespace cling { // declaration: cling/Utils/UTF8.h & cling/Interpreter/RuntimePrintValue.h template + CLING_LIB_EXPORT std::string toUTF8(const T* const Str, size_t N, const char Prefix); template <> + CLING_LIB_EXPORT std::string toUTF8(const char16_t* const Str, size_t N, const char Prefix) { return utf8Value(Str, N, Prefix, encodeUTF8); } template <> + CLING_LIB_EXPORT std::string toUTF8(const char32_t* const Str, size_t N, const char Prefix) { return utf8Value(Str, N, Prefix, encodeUTF8); } template <> + CLING_LIB_EXPORT std::string toUTF8(const wchar_t* const Str, size_t N, const char Prefix) { static_assert(sizeof(wchar_t) == sizeof(char16_t) || @@ -487,6 +513,7 @@ namespace cling { } template <> + CLING_LIB_EXPORT std::string toUTF8(const char* const Str, size_t N, const char Prefix) { return utf8Value(Str, N, Prefix, quoteString); } @@ -500,14 +527,17 @@ namespace cling { return encodeUTF8(Src->data(), Src->size(), Prefix); } + CLING_LIB_EXPORT std::string printValue(const std::u16string* Val) { return toUTF8(Val, 'u'); } + CLING_LIB_EXPORT std::string printValue(const std::u32string* Val) { return toUTF8(Val, 'U'); } + CLING_LIB_EXPORT std::string printValue(const std::wstring* Val) { return toUTF8(Val, 'L'); } @@ -527,14 +557,17 @@ namespace cling { return Strm.str(); } + CLING_LIB_EXPORT std::string printValue(const char16_t *Val) { return toUnicode(Val, 'u'); } + CLING_LIB_EXPORT std::string printValue(const char32_t *Val) { return toUnicode(Val, 'U'); } + CLING_LIB_EXPORT std::string printValue(const wchar_t *Val) { return toUnicode(Val, 'L', 'x'); } @@ -916,6 +949,7 @@ static std::string printUnpackedClingValue(const Value &V) { namespace cling { // cling::Value + CLING_LIB_EXPORT std::string printValue(const Value *value) { cling::smallstream strm; From 62d3c3c828a3e09e0e90381614a4411026ffe498 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 21 May 2021 14:30:52 +0200 Subject: [PATCH 2/7] [cmake] Improve cling/llvm visibility setting from ROOT: For ROOT, all of llvm, clang, and cling want CMAKE_VISIBILITY_INLINES_HIDDEN, so move it here, and use the CMake interface instead of passing a CXX_FLAG. --- interpreter/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt index c98a6265cebaa..da69aabff9098 100644 --- a/interpreter/CMakeLists.txt +++ b/interpreter/CMakeLists.txt @@ -131,6 +131,7 @@ else() set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_C_VISIBILITY_PRESET hidden) endif() +set(CMAKE_VISIBILITY_INLINES_HIDDEN "ON") #--- Build LLVM/Clang with modules ----------------------------------------------------------------- if(cxxmodules) @@ -463,7 +464,7 @@ if (builtin_cling) set(CLING_CXXFLAGS " ${LLVM_DEFS} -DNOMINMAX -D_XKEYCHECK_H") else() # FIXME: Work hard to remove -Wno-shadow and -Wno-unused-parameter - set(CLING_CXXFLAGS " ${LLVM_DEFS} -fvisibility=hidden -fno-strict-aliasing -Wwrite-strings -Wno-shadow -Wno-unused-parameter -Wno-deprecated-declarations") + set(CLING_CXXFLAGS " ${LLVM_DEFS} -fno-strict-aliasing -Wwrite-strings -Wno-shadow -Wno-unused-parameter -Wno-deprecated-declarations") endif() # Set the flags in the parent scope for the rest of the cling-based libraries in ROOT. From 99e91475f92f2414ef3d12cd642fb9903244e11d Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 21 May 2021 16:35:35 +0200 Subject: [PATCH 3/7] [cmake] Remove warning suppression fixed by llvm9. --- core/dictgen/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/dictgen/CMakeLists.txt b/core/dictgen/CMakeLists.txt index 7f5aca4961a6d..ecf12744cfae7 100644 --- a/core/dictgen/CMakeLists.txt +++ b/core/dictgen/CMakeLists.txt @@ -14,8 +14,6 @@ # These files are linked into rootcling_stage1 and libCling. rootcling accesses # them through rootcling_impl. -ROOT_ADD_COMPILE_OPTIONS(-Wno-class-memaccess) - ROOT_OBJECT_LIBRARY(Dictgen BaseSelectionRule.cxx ClassSelectionRule.cxx From 04531492a8855712d8ed4bcf517d339361741173 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 21 May 2021 16:35:49 +0200 Subject: [PATCH 4/7] [cmake] Set visibility in targets depending on cling: Instead of relying on CLING_CXXFLAGS to collect as needed, set the visbility explicitly, and use target_properties instead of CMAKE_CXXFLAGS. --- core/clingutils/CMakeLists.txt | 5 ++++- core/dictgen/CMakeLists.txt | 5 ++++- core/foundation/CMakeLists.txt | 5 ++++- core/metacling/src/CMakeLists.txt | 7 +++++-- main/CMakeLists.txt | 9 ++++----- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/core/clingutils/CMakeLists.txt b/core/clingutils/CMakeLists.txt index a50dca214f6a2..b470eb1e654c9 100644 --- a/core/clingutils/CMakeLists.txt +++ b/core/clingutils/CMakeLists.txt @@ -36,7 +36,10 @@ target_include_directories(ClingUtils PRIVATE # headers from our builtin clang. That's an issue when we are building with bultin_llvm=Off # and we have installed clang headers, too. target_include_directories(ClingUtils SYSTEM PRIVATE ${CLANG_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS}") +set_target_properties(ClingUtils PROPERTIES + COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS}" + VISIBILITY_INLINES_HIDDEN "ON" +) ROOT_INSTALL_HEADERS() diff --git a/core/dictgen/CMakeLists.txt b/core/dictgen/CMakeLists.txt index ecf12744cfae7..f1b9156f08e00 100644 --- a/core/dictgen/CMakeLists.txt +++ b/core/dictgen/CMakeLists.txt @@ -46,8 +46,11 @@ target_include_directories(Dictgen PRIVATE # headers from our builtin clang. That's an issue when we are building with bultin_llvm=Off # and we have installed clang headers, too. target_include_directories(Dictgen SYSTEM PRIVATE ${CLANG_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS}) +set_target_properties(Dictgen PROPERTIES + COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS}" + VISIBILITY_INLINES_HIDDEN "ON" +) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS}") CHECK_CXX_COMPILER_FLAG("-fno-rtti" CXX_HAS_fno_rtti) if(CXX_HAS_fno_rtti) set_source_files_properties(src/rootcling_impl.cxx PROPERTIES COMPILE_FLAGS "-fno-rtti") diff --git a/core/foundation/CMakeLists.txt b/core/foundation/CMakeLists.txt index 9cbc64ebd0cad..8d0f6ffdd3c09 100644 --- a/core/foundation/CMakeLists.txt +++ b/core/foundation/CMakeLists.txt @@ -63,7 +63,10 @@ if(MSVC) target_include_directories(Foundation_Stage1 PRIVATE ${CMAKE_SOURCE_DIR}/core/winnt/inc) endif() -set_target_properties(Foundation_Stage1 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${CLING_CXXFLAGS}") +set_target_properties(Foundation_Stage1 PROPERTIES + COMPILE_FLAGS "${COMPILE_FLAGS} ${CLING_CXXFLAGS}" + VISIBILITY_INLINES_HIDDEN "ON" +) ROOT_INSTALL_HEADERS(${FOUNDATION_HEADER_DIRS}) ROOT_ADD_TEST_SUBDIRECTORY(test) diff --git a/core/metacling/src/CMakeLists.txt b/core/metacling/src/CMakeLists.txt index d571e9561ad98..8cbbe4ba089ce 100644 --- a/core/metacling/src/CMakeLists.txt +++ b/core/metacling/src/CMakeLists.txt @@ -8,8 +8,6 @@ # symbols from libCore. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS}") - if(MSVC) set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/TClingCallbacks.cxx COMPILE_FLAGS -GR-) set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/TClingRdictModuleFileExtension.cxx COMPILE_FLAGS -GR-) @@ -63,6 +61,11 @@ target_include_directories(MetaCling PRIVATE ${CMAKE_BINARY_DIR}/ginclude ) +set_target_properties(MetaCling PROPERTIES + COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS}" + VISIBILITY_INLINES_HIDDEN "ON" +) + if(MSVC) target_include_directories(MetaCling PRIVATE ${CMAKE_SOURCE_DIR}/core/winnt/inc diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index d3e7d524306f8..4694ecb58ce4e 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -74,11 +74,10 @@ install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE_Development_Main} -O - configure_file(python/cmdLineUtils.py ${localruntimedir}/cmdLineUtils.py @ONLY) -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLING_CXXFLAGS} ") -else() - set_source_files_properties(src/rootcling.cxx PROPERTIES COMPILE_FLAGS ${CLING_CXXFLAGS}) -endif() +set_source_files_properties(src/rootcling.cxx PROPERTIES + COMPILE_FLAGS ${CLING_CXXFLAGS} + VISIBILITY_INLINES_HIDDEN "ON" +) ROOT_EXECUTABLE(rootcling src/rootcling.cxx LIBRARIES RIO Cling Core) From 1451460f63e8b0d8d37de834a3ef84bbd9c39486 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 21 May 2021 14:32:01 +0200 Subject: [PATCH 5/7] [cmake] Forbid semantic-interposition for libCling: To prevent non-ROOT LLVM-libraries from replacing the symbols cling needs (with possible version mismatches), tell GCC to just always resolve calls to dynamic symbols to symbols from libCling itself. --- interpreter/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt index da69aabff9098..e3884cddbb27f 100644 --- a/interpreter/CMakeLists.txt +++ b/interpreter/CMakeLists.txt @@ -131,6 +131,9 @@ else() set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_C_VISIBILITY_PRESET hidden) endif() +if (NOT MSVC AND NOT APPLE) + ROOT_ADD_CXX_FLAG(CMAKE_CXX_FLAGS "-fno-semantic-interposition") +endif() set(CMAKE_VISIBILITY_INLINES_HIDDEN "ON") #--- Build LLVM/Clang with modules ----------------------------------------------------------------- From 478c37ec7a98fc11d294945b9b2958fabe925475 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Wed, 19 May 2021 12:06:46 +0200 Subject: [PATCH 6/7] [cmake] Simplify visibility setting: Rather than string-replacing visibility, use the CMake interface. Do not set visibility in the ROOT case; ROOT can handle that just fine itself. ROOT actually does *not* need visibility=default, now that the few symbols that are required for using cling (apart from clingtest) are explicitly requested through attributes. --- interpreter/cling/CMakeLists.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interpreter/cling/CMakeLists.txt b/interpreter/cling/CMakeLists.txt index 416a8a6986287..65b14b2711eef 100644 --- a/interpreter/cling/CMakeLists.txt +++ b/interpreter/cling/CMakeLists.txt @@ -290,10 +290,6 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) endforeach () endif () -# Lots of cling is needed at runtime (e.g. Value, or Interpreter::Evaluate()). -# The JIT needs to be able to resolve these symbols from cling; unhide them. -string(REPLACE "-fvisibility=hidden" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - # The package needs to be compiler without RTTI information if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-") @@ -324,8 +320,11 @@ string(REGEX REPLACE "([0-9]).[0-9]+~[a-zA-Z]+" "\\1" CLING_VERSION_MAJOR ${CLIN string(REGEX REPLACE "[0-9].([0-9]+)~[a-zA-Z]+" "\\1" CLING_VERSION_MINOR ${CLING_VERSION}) if(DEFINED ROOT_BINARY_DIR) - # Building as part of ROOT. + # Building as part of ROOT; visibility is "inherited" from ROOT/interpreter. set(CLING_VERSION ROOT_${CLING_VERSION}) +else() + # Lots of cling is needed at runtime (e.g. Value, or Interpreter::Evaluate()). + # The JIT needs to be able to resolve these symbols from cling; unhide them. set(CMAKE_CXX_VISIBILITY_PRESET default) set(CMAKE_C_VISIBILITY_PRESET default) set(CMAKE_VISIBILITY_INLINES_HIDDEN "ON") From fee73ea7759969f1d651f86d795ff8a655f7aae9 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Wed, 19 May 2021 12:07:32 +0200 Subject: [PATCH 7/7] [cling] Remove symbols explicitly exported through CLING_EXPORT. --- .../cling/lib/Interpreter/RequiredSymbols.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/RequiredSymbols.cpp b/interpreter/cling/lib/Interpreter/RequiredSymbols.cpp index c43cfa741daa8..6cf110da051f7 100644 --- a/interpreter/cling/lib/Interpreter/RequiredSymbols.cpp +++ b/interpreter/cling/lib/Interpreter/RequiredSymbols.cpp @@ -15,31 +15,18 @@ #include "cling/Utils/Output.h" #include "clang/AST/Type.h" -extern "C" -void* cling_runtime_internal_throwIfInvalidPointer(void* Sema, void* Expr, - const void* Arg); - namespace cling { namespace internal { void symbol_requester() { const char* const argv[] = {"libcling__symbol_requester", 0}; Interpreter I(1, argv); - //cling_PrintValue(0); - // sharedPtr is needed for SLC6 with devtoolset2: - // Redhat re-uses libstdc++ from GCC 4.4 and patches missing symbols into - // the binary through an archive. We need to pull more symbols from the - // archive to make them available to cling. This list will possibly need to - // grow... - std::shared_ptr sp; - Interpreter* SLC6DevToolSet = (Interpreter*)(void*)&sp; - LookupHelper h(0,SLC6DevToolSet); + LookupHelper h(0, &I); h.findType("", LookupHelper::NoDiagnostics); h.findScope("", LookupHelper::NoDiagnostics); h.findFunctionProto(0, "", "", LookupHelper::NoDiagnostics); h.findFunctionArgs(0, "", "", LookupHelper::NoDiagnostics); runtime::internal::DynamicExprInfo DEI(0,0,false); DEI.getExpr(); - cling_runtime_internal_throwIfInvalidPointer(nullptr, nullptr, nullptr); } } }