Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: reflex-support Changeset: r72456:0de503991f11 Date: 2014-07-16 12:16 -0700 http://bitbucket.org/pypy/pypy/changeset/0de503991f11/
Log: cling fixes diff --git a/pypy/module/cppyy/capi/builtin_capi.py b/pypy/module/cppyy/capi/builtin_capi.py --- a/pypy/module/cppyy/capi/builtin_capi.py +++ b/pypy/module/cppyy/capi/builtin_capi.py @@ -3,6 +3,7 @@ import reflex_capi as backend #import cint_capi as backend +#import cling_capi as backend from pypy.module.cppyy.capi.capi_types import C_SCOPE, C_TYPE, C_OBJECT,\ C_METHOD, C_INDEX, C_INDEX_ARRAY, WLAVC_INDEX,\ diff --git a/pypy/module/cppyy/capi/cling_capi.py b/pypy/module/cppyy/capi/cling_capi.py --- a/pypy/module/cppyy/capi/cling_capi.py +++ b/pypy/module/cppyy/capi/cling_capi.py @@ -14,12 +14,13 @@ (config_stat, incdir) = commands.getstatusoutput("root-config --incdir") if os.environ.get("ROOTSYS"): - if config_stat != 0: # presumably Reflex-only - rootincpath = [os.path.join(os.environ["ROOTSYS"], "interpreter/cling/include"), - os.path.join(os.environ["ROOTSYS"], "interpreter/llvm/inst/include")] + rootincpath = [os.path.join(os.environ["ROOTSYS"], "interpreter/cling/include"), + os.path.join(os.environ["ROOTSYS"], "interpreter/llvm/inst/include")] + if config_stat != 0: + rootincpath.append(os.path.join(os.environ["ROOTSYS"], "include")) rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")] else: - rootincpath = [incdir] + rootincpath.append(incdir) rootlibpath = commands.getoutput("root-config --libdir").split() else: if config_stat == 0: @@ -45,7 +46,7 @@ includes=["clingcwrapper.h"], library_dirs=rootlibpath, libraries=["Cling"], - compile_extra=["-fno-strict-aliasing"], + compile_extra=["-fno-strict-aliasing", "-std=c++11"], use_cpp_linker=True, ) diff --git a/pypy/module/cppyy/src/clingcwrapper.cxx b/pypy/module/cppyy/src/clingcwrapper.cxx --- a/pypy/module/cppyy/src/clingcwrapper.cxx +++ b/pypy/module/cppyy/src/clingcwrapper.cxx @@ -21,7 +21,7 @@ #include "cling/Interpreter/DynamicLibraryManager.h" #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/LookupHelper.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" #include "cling/MetaProcessor/MetaProcessor.h" #include "llvm/ADT/SmallVector.h" @@ -157,7 +157,8 @@ cppyy_scope_t cppyy_get_scope(const char* scope_name) { const cling::LookupHelper& lh = gCppyy_Cling->getLookupHelper(); const Type* type = 0; - const Decl* decl = lh.findScope(scope_name, &type, /* intantiateTemplate= */ true); + const Decl* decl = lh.findScope(scope_name, + cling::LookupHelper::NoDiagnostics, &type, /* intantiateTemplate= */ true); if (!decl) { //std::string buf = TClassEdit::InsertStd(name); //decl = lh.findScope(buf, &type, /* intantiateTemplate= */ true); @@ -190,8 +191,8 @@ // TODO: expect the below to live in libCling.so static CPPYY_Cling_Wrapper_t make_wrapper(const FunctionDecl* fdecl); -static void exec_with_valref_return(void* address, cling::StoredValueRef* ret, const FunctionDecl*); -static long long sv_to_long_long(const cling::StoredValueRef& svref); +static void exec_with_valref_return(void* address, cling::Value*, const FunctionDecl*); +static long long sv_to_long_long(const cling::Value& val); // -- TODO: expect the above to live in libCling.so @@ -200,7 +201,7 @@ if (s_wrappers.find(method) == s_wrappers.end()) { make_wrapper((FunctionDecl*)method); } - cling::StoredValueRef ret; + cling::Value ret; // std::vector<void*> arguments = build_args(nargs, args); // CPPYY_Cling_Wrapper_t cb = (CPPYY_Cling_Wrapper_t)method; exec_with_valref_return((void*)self, &ret, (FunctionDecl*)method); @@ -362,7 +363,7 @@ // R__LOCKGUARD2(gInterpreterMutex); std::cout << " NOW LOADING: " << lib_name << std::endl; - cling::StoredValueRef call_res; + cling::Value call_res; cling::Interpreter::CompilationResult comp_res = cling::Interpreter::kSuccess; std::ostringstream line; line << "#include \"" << lib_name << ".h\""; @@ -377,8 +378,8 @@ // UpdateListOfLoadedSharedLibraries(); // } switch (res) { - case cling::DynamicLibraryManager::kLoadLibSuccess: return (void*)1; - case cling::DynamicLibraryManager::kLoadLibExists: return (void*)2; + case cling::DynamicLibraryManager::kLoadLibSuccess: return (void*)1; + case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return (void*)2; default: break; }; return (void*)1; @@ -389,68 +390,130 @@ // TODO: expect the below to live in libCling.so -template <typename T> -T sv_to_long_long_u_or_not(const cling::StoredValueRef& svref) { - const cling::Value& valref = svref.get(); - QualType QT = valref.getClangType(); - if (QT.isNull()) { - print_error("sv_to_long_long_u_or_not", "null type!"); - return 0; - } - llvm::GenericValue gv = valref.getGV(); - if (QT->isMemberPointerType()) { - const MemberPointerType* MPT = - QT->getAs<MemberPointerType>(); - if (MPT->isMemberDataPointer()) { - return (T) (ptrdiff_t) gv.PointerVal; - } - return (T) gv.PointerVal; - } - if (QT->isPointerType() || QT->isArrayType() || QT->isRecordType() || - QT->isReferenceType()) { - return (T) gv.PointerVal; - } - if (const EnumType* ET = llvm::dyn_cast<EnumType>(&*QT)) { - if (ET->getDecl()->getIntegerType()->hasSignedIntegerRepresentation()) - return (T) gv.IntVal.getSExtValue(); - else - return (T) gv.IntVal.getZExtValue(); - } - if (const BuiltinType* BT = llvm::dyn_cast<BuiltinType>(&*QT)) { - if (BT->isSignedInteger()) { - return gv.IntVal.getSExtValue(); - } else if (BT->isUnsignedInteger()) { - return (T) gv.IntVal.getZExtValue(); - } else { - switch (BT->getKind()) { - case BuiltinType::Float: - return (T) gv.FloatVal; - case BuiltinType::Double: - return (T) gv.DoubleVal; - case BuiltinType::LongDouble: - // FIXME: Implement this! - break; - case BuiltinType::NullPtr: - // C++11 nullptr - return 0; - default: break; - } +template <typename returnType> +returnType sv_to(const cling::Value& val) +{ + QualType QT = val.getType(); + if (QT->isMemberPointerType()) { + const MemberPointerType* MPT = QT->getAs<MemberPointerType>(); + if (MPT->isMemberDataPointer()) { + return (returnType) (ptrdiff_t)val.getPtr(); } - } - print_error("sv_to_long_long_u_or_not", "cannot handle this type!"); - QT->dump(); - return 0; -} + return (returnType) (long) val.getPtr(); + } + if (QT->isPointerType() || QT->isArrayType() || QT->isRecordType() || + QT->isReferenceType()) { + return (returnType) (long) val.getPtr(); + } + if (const EnumType* ET = dyn_cast<EnumType>(&*QT)) { + if (ET->getDecl()->getIntegerType()->hasSignedIntegerRepresentation()) + return (returnType) val.getLL(); + else + return (returnType) val.getULL(); + } + if (const BuiltinType* BT = + dyn_cast<BuiltinType>(&*QT)) { + // + // WARNING!!! + // + // This switch is organized in order-of-declaration + // so that the produced assembly code is optimal. + // Do not reorder! + // + switch (BT->getKind()) { + case BuiltinType::Void: + // CINT used to expect a result of 0. + return (returnType) 0; + break; + // + // Unsigned Types + // + case BuiltinType::Bool: + case BuiltinType::Char_U: // char on targets where it is unsigned + case BuiltinType::UChar: + return (returnType) val.getULL(); + break; -static long long sv_to_long_long(const cling::StoredValueRef& svref) { - return sv_to_long_long_u_or_not<long long>(svref); + case BuiltinType::WChar_U: + // wchar_t on targets where it is unsigned + // The standard doesn't allow to specify signednedd of wchar_t + // thus this maps simply to wchar_t. + return (returnType) (wchar_t) val.getULL(); + break; + + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + return (returnType) val.getULL(); + break; + + case BuiltinType::UInt128: + // __uint128_t + break; + + // + // Signed Types + // + case BuiltinType::Char_S: // char on targets where it is signed + case BuiltinType::SChar: + return (returnType) val.getLL(); + break; + + case BuiltinType::WChar_S: + // wchar_t on targets where it is signed + // The standard doesn't allow to specify signednedd of wchar_t + // thus this maps simply to wchar_t. + return (returnType) (wchar_t) val.getLL(); + break; + + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + return (returnType) val.getLL(); + break; + + case BuiltinType::Int128: + break; + + case BuiltinType::Half: + // half in OpenCL, __fp16 in ARM NEON + break; + + case BuiltinType::Float: + return (returnType) val.getFloat(); + break; + case BuiltinType::Double: + return (returnType) val.getDouble(); + break; + case BuiltinType::LongDouble: + return (returnType) val.getLongDouble(); + break; + + case BuiltinType::NullPtr: + return (returnType) 0; + break; + + default: + break; + } + } + print_error("sv_to", "invalid type"); + QT->dump(); + return 0; } static -unsigned long long sv_to_ulong_long(const cling::StoredValueRef& svref) { - return sv_to_long_long_u_or_not<unsigned long long>(svref); +long long sv_to_long_long(const cling::Value& val) { + return sv_to<long long>(val); } - +static +unsigned long long sv_to_ulong_long(const cling::Value& val) { + return sv_to<unsigned long long>(val); +} namespace { @@ -772,230 +835,168 @@ (*wrapper)(address, (int)0/*num_args*/, (void**)vp_ary.data(), ret); } +static void +exec_with_valref_return(void* address, cling::Value* ret) const +{ + if (!ret) { + exec(address, 0); + return; + } + std::cout << " USING DECL: " << fdecl << std::endl; + const FunctionDecl* FD = fMethod->GetMethodDecl(); + ASTContext& Context = FD->getASTContext(); -static void exec_with_valref_return(void* address, cling::StoredValueRef* ret, const FunctionDecl* fdecl) { - if (!ret) { - exec(address, 0, fdecl); - return; - } - std::cout << " USING DECL: " << fdecl << std::endl; - fdecl->dump(); - ASTContext& Context = fdecl->getASTContext(); + if (const CXXConstructorDecl* CD = dyn_cast<CXXConstructorDecl>(FD)) { + const TypeDecl* TD = dyn_cast<TypeDecl>(CD->getDeclContext()); + QualType ClassTy(TD->getTypeForDecl(), 0); + QualType QT = Context.getLValueReferenceType(ClassTy); + *ret = cling::Value(QT, fInterp); + // Store the new()'ed address in getPtr() + exec(address, &ret->getPtr()); + return; + } + QualType QT = FD->getReturnType().getCanonicalType(); + if (QT->isReferenceType()) { + *ret = cling::Value(QT, 0); + exec(address, &ret->getPtr()); + return; + } + else if (QT->isMemberPointerType()) { + const MemberPointerType* MPT = QT->getAs<MemberPointerType>(); + if (MPT->isMemberDataPointer()) { + // A member data pointer is a actually a struct with one + // member of ptrdiff_t, the offset from the base of the object + // storage to the storage for the designated data member. + // But that's not relevant: we use it as a non-builtin, allocated + // type. + *ret = cling::Value(QT, fInterp); + exec(address, ret->getPtr()); + return; + } + // We are a function member pointer. + *ret = cling::Value(QT, fInterp); + exec(address, &ret->getPtr()); + return; + } + else if (QT->isPointerType() || QT->isArrayType()) { + // Note: ArrayType is an illegal function return value type. + *ret = cling::Value(QT, 0); + exec(address, &ret->getPtr()); + return; + } + else if (QT->isRecordType()) { + *ret = cling::Value(QT, fInterp); + exec(address, ret->getPtr()); + return; + } + else if (const EnumType* ET = dyn_cast<EnumType>(&*QT)) { + // Note: We may need to worry about the underlying type + // of the enum here. + (void) ET; + *ret = cling::Value(QT, 0); + execWithLL<int>(address, QT, ret); + return; + } + else if (const BuiltinType* BT = dyn_cast<BuiltinType>(&*QT)) { + *ret = cling::Value(QT, 0); + switch (BT->getKind()) { + case BuiltinType::Void: + exec(address, 0); + break; - if (const CXXConstructorDecl* CD = llvm::dyn_cast<CXXConstructorDecl>(fdecl)) { - const TypeDecl* TD = llvm::dyn_cast<TypeDecl>(CD->getDeclContext()); - QualType ClassTy(TD->getTypeForDecl(), 0); - QualType QT = Context.getLValueReferenceType(ClassTy); - llvm::GenericValue gv; - exec(address, &gv.PointerVal, fdecl); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(gv, QT)); - return; - } - QualType QT = fdecl->getResultType().getCanonicalType(); - if (QT->isReferenceType()) { - llvm::GenericValue gv; - exec(address, &gv.PointerVal, fdecl); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(gv, QT)); - return; - } - else if (QT->isMemberPointerType()) { - const MemberPointerType* MPT = - QT->getAs<MemberPointerType>(); - if (MPT->isMemberDataPointer()) { - // A member data pointer is a actually a struct with one - // member of ptrdiff_t, the offset from the base of the object - // storage to the storage for the designated data member. - llvm::GenericValue gv; - exec(address, &gv.PointerVal, fdecl); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(gv, QT)); - return; - } - // We are a function member pointer. - llvm::GenericValue gv; - exec(address, &gv.PointerVal, fdecl); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(gv, QT)); - return; - } - else if (QT->isPointerType() || QT->isArrayType()) { - // Note: ArrayType is an illegal function return value type. - llvm::GenericValue gv; - exec(address, &gv.PointerVal, fdecl); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(gv, QT)); - return; - } - else if (QT->isRecordType()) { - uint64_t size = Context.getTypeSizeInChars(QT).getQuantity(); - void* p = ::operator new(size); - exec(address, p, fdecl); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(llvm::PTOGV(p), QT)); - return; - } - else if (const EnumType* ET = llvm::dyn_cast<EnumType>(&*QT)) { - // Note: We may need to worry about the underlying type - // of the enum here. - (void) ET; - uint64_t numBits = Context.getTypeSize(QT); - int retVal = 0; - exec(address, &retVal, fdecl); - llvm::GenericValue gv; - gv.IntVal = llvm::APInt(numBits, (uint64_t)retVal, true /*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy( - *gCppyy_Cling, cling::Value(gv, QT)); - return; - } - else if (const BuiltinType* BT = llvm::dyn_cast<BuiltinType>(&*QT)) { - llvm::GenericValue gv; + // + // Unsigned Types + // + case BuiltinType::Bool: + execWithULL<bool>(address, QT, ret); + break; + case BuiltinType::Char_U: // char on targets where it is unsigned + case BuiltinType::UChar: + execWithULL<char>(address, QT, ret); + break; + case BuiltinType::WChar_U: + // wchar_t on targets where it is unsigned. + // The standard doesn't allow to specify signednedd of wchar_t + // thus this maps simply to wchar_t. + execWithULL<wchar_t>(address, QT, ret); + break; + case BuiltinType::Char16: + print_error("exec_with_valref_return", "invalid type: char16_t"); + break; + case BuiltinType::Char32: + print_error("exec_with_valref_return", "invalid type char32_t"); + break; + case BuiltinType::UShort: + execWithULL<unsigned short>(address, QT, ret); + break; + case BuiltinType::UInt: + execWithULL<unsigned int>(address, QT, ret); + break; + case BuiltinType::ULong: + execWithULL<unsigned long>(address, QT, ret); + break; + case BuiltinType::ULongLong: + execWithULL<unsigned long long>(address, QT, ret); + break; + case BuiltinType::UInt128: + print_error("exec_with_valref_return", "invalid type __uint128_t"); + break; - uint64_t numBits = Context.getTypeSize(QT); - switch (BT->getKind()) { - // - // builtin types - // - case BuiltinType::Void: { - exec(address, 0, fdecl); - return; - } - // - // unsigned integral types - // - case BuiltinType::Bool: { - bool retVal = false; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t)retVal, false /*isSigned*/); + // + // Signed Types + // + case BuiltinType::Char_S: // char on targets where it is signed + case BuiltinType::SChar: + execWithLL<signed char>(address, QT, ret); break; - } - case BuiltinType::Char_U: { - // char on targets where it is unsigned - char retVal = '\0'; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - case BuiltinType::UChar: { - unsigned char retVal = '\0'; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - case BuiltinType::WChar_U: { - // wchar_t on targets where it is unsigned. - // The standard doesn't allow to specify signedness of wchar_t - // thus this maps simply to wchar_t. - wchar_t retVal = L'\0'; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - case BuiltinType::UShort: { - unsigned short retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - case BuiltinType::UInt: { - unsigned int retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - case BuiltinType::ULong: { - // unsigned long - unsigned long retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - case BuiltinType::ULongLong: { - // unsigned long long - unsigned long long retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, false /*isSigned*/); - break; - } - // - // signed integral types - // - case BuiltinType::Char_S: { - // char on targets where it is signed - char retVal = '\0'; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); - break; - } - case BuiltinType::SChar: { - // signed char - signed char retVal = '\0'; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); - break; - } - case BuiltinType::WChar_S: { + case BuiltinType::WChar_S: // wchar_t on targets where it is signed. // The standard doesn't allow to specify signednedd of wchar_t // thus this maps simply to wchar_t. - wchar_t retVal = L'\0'; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); + execWithLL<wchar_t>(address, QT, ret); break; - } - case BuiltinType::Short: { - // short - short retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); + case BuiltinType::Short: + execWithLL<short>(address, QT, ret); break; - } - case BuiltinType::Int: { - // int - int retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); + case BuiltinType::Int: + execWithLL<int>(address, QT, ret); break; - } - case BuiltinType::Long: { - long retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); + case BuiltinType::Long: + execWithLL<long>(address, QT, ret); break; - } - case BuiltinType::LongLong: { - long long retVal = 0; - exec(address, &retVal, fdecl); - gv.IntVal = llvm::APInt(numBits, (uint64_t) retVal, true /*isSigned*/); + case BuiltinType::LongLong: + execWithLL<long long>(address, QT, ret); break; - } - case BuiltinType::Float: { - exec(address, &gv.FloatVal, fdecl); + case BuiltinType::Int128: + print_error("exec_with_valref_return", "invalid type __int128_t"); break; - } - case BuiltinType::Double: { - exec(address, &gv.DoubleVal, fdecl); + case BuiltinType::Half: + // half in OpenCL, __fp16 in ARM NEON + print_error("exec_with_valref_return", "invalid type Half"); break; - } - case BuiltinType::Char16: - case BuiltinType::Char32: - case BuiltinType::Half: - case BuiltinType::Int128: - case BuiltinType::UInt128: - case BuiltinType::LongDouble: - case BuiltinType::NullPtr: - default: { - print_error("exec_with_valref", "unsupported return type"); - return; - } - } - - *ret = cling::StoredValueRef::bitwiseCopy(*gCppyy_Cling, cling::Value(gv, QT)); - return; - } - - std::cout << "exec_with_valref: some error occurred ... " << std::endl; + case BuiltinType::Float: + exec(address, &ret->getFloat()); + break; + case BuiltinType::Double: + exec(address, &ret->getDouble()); + break; + case BuiltinType::LongDouble: + exec(address, &ret->getLongDouble()); + break; + // + // Language-Specific Types + // + case BuiltinType::NullPtr: + // C++11 nullptr + print_error("exec_with_valref_return", "invalid type nullptr"); + break; + default: + break; + } + return; + } + print_error("exec_with_valref_return", "unrecognized return type"); + QT->dump(); } _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit