[pypy-commit] pypy cling-support: From Aditi: first stab at new Cling backend, based off the C++ Cppyy.cxx

wlav pypy.commits at gmail.com
Mon Jun 27 17:02:50 EDT 2016


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: cling-support
Changeset: r85418:1e669815cd70
Date: 2016-06-27 13:59 -0700
http://bitbucket.org/pypy/pypy/changeset/1e669815cd70/

Log:	From Aditi: first stab at new Cling backend, based off the C++
	Cppyy.cxx

diff too long, truncating to 2000 out of 3541 lines

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -77,3 +77,5 @@
 ^.hypothesis/
 ^release/
 ^rpython/_cache$
+
+pypy/module/cppyy/.+/*\.pcm
diff --git a/pypy/module/cppyy/bench/Makefile b/pypy/module/cppyy/bench/Makefile
--- a/pypy/module/cppyy/bench/Makefile
+++ b/pypy/module/cppyy/bench/Makefile
@@ -26,4 +26,4 @@
 
 bench02Dict_reflex.so: bench02.h bench02.cxx bench02.xml
 	$(genreflex) bench02.h $(genreflexflags) --selection=bench02.xml -I$(ROOTSYS)/include
-	g++ -o $@ bench02.cxx bench02_rflx.cpp -I$(ROOTSYS)/include -shared -lReflex -lHistPainter `root-config --libs` $(cppflags) $(cppflags2)
+	g++ -o $@ bench02.cxx bench02_rflx.cpp -I$(ROOTSYS)/include -shared -std=c++14 -lHistPainter `root-config --libs` $(cppflags) $(cppflags2)
diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -9,8 +9,8 @@
 # the selection of the desired backend (default is Reflex).
 
 # choose C-API access method:
-from pypy.module.cppyy.capi.loadable_capi import *
-#from pypy.module.cppyy.capi.builtin_capi import *
+#from pypy.module.cppyy.capi.loadable_capi import *
+from pypy.module.cppyy.capi.builtin_capi import *
 
 from pypy.module.cppyy.capi.capi_types import C_OBJECT,\
     C_NULL_TYPE, C_NULL_OBJECT
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
@@ -1,7 +1,8 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rlib import jit
 
-import reflex_capi as backend
+import cling_capi as backend
+#import reflex_capi as backend
 #import cint_capi as backend
 
 from pypy.module.cppyy.capi.capi_types import C_SCOPE, C_TYPE, C_OBJECT,\
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
@@ -16,7 +16,8 @@
 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")]
+                       os.path.join(os.environ["ROOTSYS"], "interpreter/llvm/inst/include"),
+                       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]
@@ -39,13 +40,21 @@
 
 std_string_name = 'std::basic_string<char>'
 
+# force loading (and exposure) of libCore symbols
+with rffi.scoped_str2charp('libCore.so') as ll_libname:
+    _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
+
+# require local translator path to pickup common defs
+from rpython.translator import cdir
+translator_c_dir = py.path.local(cdir)
+
 eci = ExternalCompilationInfo(
     separate_module_files=[srcpath.join("clingcwrapper.cxx")],
-    include_dirs=[incpath] + rootincpath,
+    include_dirs=[incpath, translator_c_dir] + rootincpath,
     includes=["clingcwrapper.h"],
     library_dirs=rootlibpath,
     libraries=["Cling"],
-    compile_extra=["-fno-strict-aliasing"],
+    compile_extra=["-fno-strict-aliasing", "-std=c++14"],
     use_cpp_linker=True,
 )
 
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -735,7 +735,7 @@
 
     type_info = (
         (rffi.LONG,       ("long", "long int")),
-        (rffi.LONGLONG,   ("long long", "long long int")),
+        (rffi.LONGLONG,   ("long long", "long long int", "Long64_t")),
     )
 
     for c_type, names in type_info:
@@ -743,6 +743,7 @@
             _immutable_ = True
             def __init__(self, space, default):
                 self.default = rffi.cast(self.c_type, capi.c_strtoll(space, default))
+
         class ConstRefConverter(ConstRefNumericTypeConverterMixin, BasicConverter):
             _immutable_ = True
             libffitype = jit_libffi.types.pointer
@@ -761,7 +762,7 @@
         (rffi.USHORT,     ("unsigned short", "unsigned short int")),
         (rffi.UINT,       ("unsigned", "unsigned int")),
         (rffi.ULONG,      ("unsigned long", "unsigned long int")),
-        (rffi.ULONGLONG,  ("unsigned long long", "unsigned long long int")),
+        (rffi.ULONGLONG,  ("unsigned long long", "unsigned long long int", "ULong64_t")),
     )
 
     for c_type, names in type_info:
diff --git a/pypy/module/cppyy/include/cpp_cppyy.h b/pypy/module/cppyy/include/cpp_cppyy.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/include/cpp_cppyy.h
@@ -0,0 +1,143 @@
+#ifndef PYROOT_CPPYY_H
+#define PYROOT_CPPYY_H
+
+// Standard
+#include <string>
+#include <vector>
+#include <stddef.h>
+
+//ROOT types
+   typedef long	       Long_t;
+   typedef unsigned long ULong_t;
+   typedef long long   Long64_t;
+   typedef unsigned long long ULong64_t;
+   typedef float       Float_t;
+   typedef double      Double_t;
+   typedef long double LongDouble_t;
+   typedef bool        Bool_t;
+   typedef char        Char_t;
+   typedef unsigned char UChar_t;
+   typedef short       Short_t;
+   typedef unsigned short UShort_t;
+   typedef int	       Int_t;
+   typedef unsigned int UInt_t;
+
+namespace Cppyy {
+   typedef ptrdiff_t   TCppScope_t;
+   typedef TCppScope_t TCppType_t;
+   typedef void*       TCppObject_t;
+   typedef ptrdiff_t   TCppMethod_t;
+
+   typedef Long_t      TCppIndex_t;
+   typedef void* (*TCppMethPtrGetter_t)( TCppObject_t );
+
+// name to opaque C++ scope representation -----------------------------------
+   TCppIndex_t GetNumScopes( TCppScope_t parent );
+   std::string GetScopeName( TCppScope_t parent, TCppIndex_t iscope );
+   std::string ResolveName( const std::string& cppitem_name );
+   TCppScope_t GetScope( const std::string& scope_name );
+   TCppType_t  GetTemplate( const std::string& template_name );
+   TCppType_t  GetActualClass( TCppType_t klass, TCppObject_t obj );
+   size_t      SizeOf( TCppType_t klass );
+
+   Bool_t      IsBuiltin( const std::string& type_name );
+   Bool_t      IsComplete( const std::string& type_name );
+
+   extern TCppScope_t gGlobalScope;      // for fast access
+
+// memory management ---------------------------------------------------------
+   TCppObject_t Allocate( TCppType_t type );
+   void         Deallocate( TCppType_t type, TCppObject_t instance );
+   TCppObject_t Construct( TCppType_t type );
+   void         Destruct( TCppType_t type, TCppObject_t instance );
+
+// method/function dispatching -----------------------------------------------
+   void         CallV( TCppMethod_t method, TCppObject_t self, void* args );
+   UChar_t      CallB( TCppMethod_t method, TCppObject_t self, void* args );
+   Char_t       CallC( TCppMethod_t method, TCppObject_t self, void* args );
+   Short_t      CallH( TCppMethod_t method, TCppObject_t self, void* args );
+   Int_t        CallI( TCppMethod_t method, TCppObject_t self, void* args );
+   Long_t       CallL( TCppMethod_t method, TCppObject_t self, void* args );
+   Long64_t     CallLL( TCppMethod_t method, TCppObject_t self, void* args );
+   Float_t      CallF( TCppMethod_t method, TCppObject_t self, void* args );
+   Double_t     CallD( TCppMethod_t method, TCppObject_t self, void* args );
+   LongDouble_t CallLD( TCppMethod_t method, TCppObject_t self, void* args );
+   void*        CallR( TCppMethod_t method, TCppObject_t self, void* args );
+   Char_t*      CallS( TCppMethod_t method, TCppObject_t self, void* args );
+   TCppObject_t CallConstructor( TCppMethod_t method, TCppType_t type, void* args );
+   void         CallDestructor( TCppType_t type, TCppObject_t self );
+   TCppObject_t CallO( TCppMethod_t method, TCppObject_t self, void* args, TCppType_t result_type );
+
+   TCppMethPtrGetter_t GetMethPtrGetter( TCppScope_t scope, TCppIndex_t imeth );
+
+// handling of function argument buffer --------------------------------------
+   void*  AllocateFunctionArgs( size_t nargs );
+   void   DeallocateFunctionArgs( void* args );
+   size_t GetFunctionArgSizeof();
+   size_t GetFunctionArgTypeoffset();
+
+// scope reflection information ----------------------------------------------
+   Bool_t IsNamespace( TCppScope_t scope );
+   Bool_t IsAbstract( TCppType_t type );
+   Bool_t IsEnum( const std::string& type_name );
+
+// class reflection information ----------------------------------------------
+   std::string GetFinalName( TCppType_t type );
+   std::string GetScopedFinalName( TCppType_t type );
+   Bool_t      HasComplexHierarchy( TCppType_t type );
+   TCppIndex_t GetNumBases( TCppType_t type );
+   std::string GetBaseName( TCppType_t type, TCppIndex_t ibase );
+   Bool_t      IsSubtype( TCppType_t derived, TCppType_t base );
+   void        AddSmartPtrType( const std::string& );
+   Bool_t      IsSmartPtr( const std::string& );
+
+// calculate offsets between declared and actual type, up-cast: direction > 0; down-cast: direction < 0
+   ptrdiff_t GetBaseOffset(
+      TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror = false );
+
+// method/function reflection information ------------------------------------
+   TCppIndex_t  GetNumMethods( TCppScope_t scope );
+   TCppIndex_t  GetMethodIndexAt( TCppScope_t scope, TCppIndex_t imeth );
+   std::vector< TCppMethod_t > GetMethodsFromName( TCppScope_t scope, const std::string& name );
+
+   TCppMethod_t GetMethod( TCppScope_t scope, TCppIndex_t imeth );
+
+   std::string GetMethodName( TCppMethod_t );
+   std::string GetMethodResultType( TCppMethod_t );
+   TCppIndex_t GetMethodNumArgs( TCppMethod_t );
+   TCppIndex_t GetMethodReqArgs( TCppMethod_t );
+   std::string GetMethodArgName( TCppMethod_t, int iarg );
+   std::string GetMethodArgType( TCppMethod_t, int iarg );
+   std::string GetMethodArgDefault( TCppMethod_t, int iarg );
+   std::string GetMethodSignature( TCppScope_t scope, TCppIndex_t imeth );
+   Bool_t      IsConstMethod( TCppMethod_t );
+
+   Bool_t      IsMethodTemplate( TCppMethod_t );
+   TCppIndex_t GetMethodNumTemplateArgs( TCppScope_t scope, TCppIndex_t imeth );
+   std::string GetMethodTemplateArgName( TCppScope_t scope, TCppIndex_t imeth, TCppIndex_t iarg );
+
+   TCppIndex_t  GetGlobalOperator(
+      TCppType_t scope, TCppType_t lc, TCppScope_t rc, const std::string& op );
+
+// method properties ---------------------------------------------------------
+   Bool_t IsConstructor( TCppMethod_t method );
+   Bool_t IsPublicMethod( TCppMethod_t method );
+   Bool_t IsStaticMethod( TCppMethod_t method );
+
+// data member reflection information ----------------------------------------
+   TCppIndex_t GetNumDatamembers( TCppScope_t scope );
+   std::string GetDatamemberName( TCppScope_t scope, TCppIndex_t idata );
+   std::string GetDatamemberType( TCppScope_t scope, TCppIndex_t idata );
+   ptrdiff_t   GetDatamemberOffset( TCppScope_t scope, TCppIndex_t idata );
+   TCppIndex_t GetDatamemberIndex( TCppScope_t scope, const std::string& name );
+
+// data member properties ----------------------------------------------------
+   Bool_t IsPublicData( TCppScope_t scope, TCppIndex_t idata );
+   Bool_t IsStaticData( TCppScope_t scope, TCppIndex_t idata );
+   Bool_t IsConstData( TCppScope_t scope, TCppIndex_t idata );
+   Bool_t IsEnumData( TCppScope_t scope, TCppIndex_t idata );
+   Int_t  GetDimensionSize( TCppScope_t scope, TCppIndex_t idata, int dimension );
+
+} // namespace Cppyy
+
+#endif // ifndef PYROOT_CPPYY_H
diff --git a/pypy/module/cppyy/include/cppyy.h b/pypy/module/cppyy/include/cppyy.h
--- a/pypy/module/cppyy/include/cppyy.h
+++ b/pypy/module/cppyy/include/cppyy.h
@@ -1,6 +1,8 @@
 #ifndef CPPYY_CPPYY
 #define CPPYY_CPPYY
 
+#include "cpp_cppyy.h"
+
 #ifdef __cplusplus
 struct CPPYY_G__DUMMY_FOR_CINT7 {
 #else
diff --git a/pypy/module/cppyy/src/callcontext.h b/pypy/module/cppyy/src/callcontext.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cppyy/src/callcontext.h
@@ -0,0 +1,101 @@
+#ifndef PYROOT_TCALLCONTEXT_H
+#define PYROOT_TCALLCONTEXT_H
+
+// Standard
+#include <vector>
+
+//Bindings
+#include "cpp_cppyy.h"
+
+//ROOT
+#include "Rtypes.h"
+
+namespace PyROOT {
+
+// general place holder for function parameters
+   struct TParameter {
+      union Value {
+         Bool_t       fBool;
+         Short_t      fShort;
+         UShort_t     fUShort;
+         Int_t        fInt;
+         UInt_t       fUInt;
+         Long_t       fLong;
+         ULong_t      fULong;
+         Long64_t     fLongLong;
+         ULong64_t    fULongLong;
+         Float_t      fFloat;
+         Double_t     fDouble;
+         LongDouble_t fLongDouble;
+         void*        fVoidp;
+      } fValue;
+      void* fRef;
+      char  fTypeCode;
+   };
+
+// extra call information
+   struct TCallContext {
+      TCallContext( std::vector< TParameter >::size_type sz = 0 ) : fArgs( sz ), fFlags( 0 ) {}
+
+      enum ECallFlags {
+         kNone           =    0,
+         kIsSorted       =    1,   // if method overload priority determined
+         kIsCreator      =    2,   // if method creates python-owned objects
+         kIsConstructor  =    4,   // if method is a C++ constructor
+         kUseHeuristics  =    8,   // if method applies heuristics memory policy
+         kUseStrict      =   16,   // if method applies strict memory policy
+         kManageSmartPtr =   32,   // if executor should manage smart pointers
+         kReleaseGIL     =   64,   // if method should release the GIL
+         kFast           =  128,   // if method should NOT handle signals
+         kSafe           =  256    // if method should return on signals
+      };
+
+   // memory handling
+      static ECallFlags sMemoryPolicy;
+      static Bool_t SetMemoryPolicy( ECallFlags e );
+
+   // signal safety
+      static ECallFlags sSignalPolicy;
+      static Bool_t SetSignalPolicy( ECallFlags e );
+
+   // payload
+      std::vector< TParameter > fArgs;
+      UInt_t fFlags;
+   };
+
+   inline Bool_t IsSorted( UInt_t flags ) {
+      return flags & TCallContext::kIsSorted;
+   }
+
+   inline Bool_t IsCreator( UInt_t flags ) {
+      return flags & TCallContext::kIsCreator;
+   }
+
+   inline Bool_t IsConstructor( UInt_t flags ) {
+      return flags & TCallContext::kIsConstructor;
+   }
+
+   inline Bool_t ManagesSmartPtr( TCallContext* ctxt ) {
+      return ctxt->fFlags & TCallContext::kManageSmartPtr;
+   }
+
+   inline Bool_t ReleasesGIL( UInt_t flags ) {
+      return flags & TCallContext::kReleaseGIL;
+   }
+
+   inline Bool_t ReleasesGIL( TCallContext* ctxt ) {
+      return ctxt ? (ctxt->fFlags & TCallContext::kReleaseGIL) : kFALSE;
+   }
+
+   inline Bool_t UseStrictOwnership( TCallContext* ctxt ) {
+      if ( ctxt && (ctxt->fFlags & TCallContext::kUseStrict) )
+         return kTRUE;
+      if ( ctxt && (ctxt->fFlags & TCallContext::kUseHeuristics) )
+         return kFALSE;
+
+      return TCallContext::sMemoryPolicy == TCallContext::kUseStrict;
+   }
+
+} // namespace PyROOT
+
+#endif // !PYROOT_TCALLCONTEXT_H
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
@@ -1,1810 +1,1364 @@
-#include "cppyy.h"
-#include "clingcwrapper.h"
+// Bindings
+#include "capi.h"
+#include "cpp_cppyy.h"
+#include "callcontext.h"
 
-/*************************************************************************
- * Copyright (C) 1995-2014, the ROOT team.                               *
- * LICENSE: LGPLv2.1; see http://root.cern.ch/drupal/content/license     *
- * CONTRIBUTORS: see http://root.cern.ch/drupal/content/contributors     *
- *************************************************************************/
+// ROOT
+#include "TBaseClass.h"
+#include "TClass.h"
+#include "TClassRef.h"
+#include "TClassTable.h"
+#include "TClassEdit.h"
+#include "TCollection.h"
+#include "TDataMember.h"
+#include "TDataType.h"
+#include "TError.h"
+#include "TFunction.h"
+#include "TGlobal.h"
+#include "TInterpreter.h"
+#include "TList.h"
+#include "TMethod.h"
+#include "TMethodArg.h"
+#include "TROOT.h"
 
-#include <stdint.h>
+// Standard
+#include <assert.h>
+#include <map>
+#include <set>
+#include <sstream>
 
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Sema/Sema.h"
+// temp
+#include <iostream>
+typedef PyROOT::TParameter TParameter;
+// --temp
 
-#include "cling/Interpreter/DynamicLibraryManager.h"
-#include "cling/Interpreter/Interpreter.h"
-#include "cling/Interpreter/LookupHelper.h"
-#include "cling/Interpreter/StoredValueRef.h"
-#include "cling/MetaProcessor/MetaProcessor.h"
 
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/Support/raw_ostream.h"
+// small number that allows use of stack for argument passing
+const int SMALL_ARGS_N = 8;
 
-#include <iostream>
-#include <map>
-#include <string>
-#include <sstream>
-#include <vector>
+// data for life time management ---------------------------------------------
+typedef std::vector< TClassRef > ClassRefs_t;
+static ClassRefs_t g_classrefs( 1 );
+static const ClassRefs_t::size_type GLOBAL_HANDLE = 1;
 
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+typedef std::map< std::string, ClassRefs_t::size_type > Name2ClassRefIndex_t;
+static Name2ClassRefIndex_t g_name2classrefidx;
 
-using namespace clang;
+typedef std::map< Cppyy::TCppMethod_t, CallFunc_t* > Method2CallFunc_t;
+static Method2CallFunc_t g_method2callfunc;
 
+typedef std::vector< TFunction > GlobalFuncs_t;
+static GlobalFuncs_t g_globalfuncs;
 
-/* cling initialization --------------------------------------------------- */
+typedef std::vector< TGlobal* > GlobalVars_t;
+static GlobalVars_t g_globalvars;
+
+// data ----------------------------------------------------------------------
+Cppyy::TCppScope_t Cppyy::gGlobalScope = GLOBAL_HANDLE;
+
+// smart pointer types
+static std::set< std::string > gSmartPtrTypes =
+   { "auto_ptr", "shared_ptr", "weak_ptr", "unique_ptr" };
+
+
+// global initialization -----------------------------------------------------
 namespace {
 
-cling::Interpreter* gCppyy_Cling;
-cling::MetaProcessor* gCppyy_MetaProcessor;
+class ApplicationStarter {
+public:
+   ApplicationStarter() {
+      // setup dummy holders for global and std namespaces
+      assert( g_classrefs.size() == GLOBAL_HANDLE );
+      g_name2classrefidx[ "" ]      = GLOBAL_HANDLE;
+      g_classrefs.push_back(TClassRef(""));
+      // ROOT ignores std/::std, so point them to the global namespace
+      g_name2classrefidx[ "std" ]   = GLOBAL_HANDLE;
+      g_name2classrefidx[ "::std" ] = GLOBAL_HANDLE;
+      // add a dummy global to refer to as null at index 0
+      g_globalvars.push_back( nullptr );
+   }
 
-struct Cppyy_InitCling { // TODO: check whether ROOT/meta's TCling is linked in
-    Cppyy_InitCling() {
-        std::vector<std::string> cling_args_storage;
-        cling_args_storage.push_back("cling4cppyy");
-
-        // TODO: get this from env
-        cling_args_storage.push_back("-I/home/wlavrijsen/rootdev/root/etc");
-
-        std::vector<const char*> interp_args;
-        for (std::vector<std::string>::const_iterator iarg = cling_args_storage.begin();
-                iarg != cling_args_storage.end(); ++iarg)
-           interp_args.push_back(iarg->c_str());
-
-        // TODO: get this from env
-        const char* llvm_resource_dir = "/home/wlavrijsen/rootdev/root/etc/cling";
-        gCppyy_Cling = new cling::Interpreter(
-            interp_args.size(), &(interp_args[0]), llvm_resource_dir);
-
-        // fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
-
-        {
-            // R__LOCKGUARD(gInterpreterMutex);
-            gCppyy_Cling->AddIncludePath("/home/wlavrijsen/rootdev/root/etc/cling");
-            gCppyy_Cling->AddIncludePath(".");
-        }
-
-        // don't check whether modules' files exist.
-        gCppyy_Cling->getCI()->getPreprocessorOpts().DisablePCHValidation = true;
-
-        // Use a stream that doesn't close its file descriptor.
-        static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /* ShouldClose */ false);
-        gCppyy_MetaProcessor = new cling::MetaProcessor(*gCppyy_Cling, fMPOuts);
-
-        gCppyy_Cling->enableDynamicLookup();
-    }
-} _init;
-
-typedef std::map<std::string, cppyy_scope_t> NamedHandles_t;
-static NamedHandles_t s_named;
-
-struct SimpleScope {
-    std::vector<FunctionDecl*> m_methods;
-    std::vector<Decl*> m_data;
-};
-
-typedef std::map<cppyy_scope_t, SimpleScope*> Scopes_t;
-static Scopes_t s_scopes;
-
-typedef std::map<cppyy_method_t, CPPYY_Cling_Wrapper_t> Wrappers_t;
-static Wrappers_t s_wrappers;
+   ~ApplicationStarter() {
+      for ( auto ifunc : g_method2callfunc )
+         gInterpreter->CallFunc_Delete( ifunc.second );
+   }
+} _applicationStarter;
 
 } // unnamed namespace
 
-
-/* local helpers --------------------------------------------------------- */
-static inline void print_error(const std::string& where, const std::string& what) {
-    std::cerr << where << ": " << what << std::endl;
+// local helpers -------------------------------------------------------------
+static inline
+TClassRef& type_from_handle( Cppyy::TCppScope_t scope )
+{
+   assert( (ClassRefs_t::size_type) scope < g_classrefs.size() );
+   return g_classrefs[ (ClassRefs_t::size_type)scope ];
 }
 
-static inline char* cppstring_to_cstring(const std::string& name) {
+// type_from_handle to go here
+static inline
+TFunction* type_get_method( Cppyy::TCppType_t klass, Cppyy::TCppIndex_t idx )
+{
+   TClassRef& cr = type_from_handle( klass );
+   if ( cr.GetClass() )
+      return (TFunction*)cr->GetListOfMethods()->At( idx );
+   assert( klass == (Cppyy::TCppType_t)GLOBAL_HANDLE );
+   return (TFunction*)idx;
+}
+
+static inline
+Cppyy::TCppScope_t declaring_scope( Cppyy::TCppMethod_t method )
+{
+   TMethod* m = dynamic_cast<TMethod*>( (TFunction*)method );
+   if ( m ) return Cppyy::GetScope( m->GetClass()->GetName() );
+   return (Cppyy::TCppScope_t)GLOBAL_HANDLE;
+}
+
+static inline
+char* cppstring_to_cstring(const std::string& name) {
     char* name_char = (char*)malloc(name.size() + 1);
     strcpy(name_char, name.c_str());
     return name_char;
 }
 
-static inline SimpleScope* scope_from_handle(cppyy_type_t handle) {
-    return s_scopes[(cppyy_scope_t)handle];
+
+// name to opaque C++ scope representation -----------------------------------
+Cppyy::TCppIndex_t Cppyy::GetNumScopes( TCppScope_t scope )
+{
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() ) return 0;   // not supported if not at global scope
+   assert( scope == (TCppScope_t)GLOBAL_HANDLE );
+   return gClassTable->Classes();
 }
 
-static inline std::string qualtype_to_string(const QualType& qt, const ASTContext& atx) {
-    std::string result;
-
-    PrintingPolicy policy(atx.getPrintingPolicy());
-    policy.SuppressTagKeyword = true;        // no class or struct keyword
-    policy.SuppressScope = true;             // force scope from a clang::ElaboratedType
-    policy.AnonymousTagLocations = false;    // no file name + line number for anonymous types
-        // The scope suppression is required for getting rid of the anonymous part of the name
-        // of a class defined in an anonymous namespace.
-    
-    qt.getAsStringInternal(result, policy);
-    return result;
+std::string Cppyy::GetScopeName( TCppScope_t parent, TCppIndex_t iscope )
+{
+// Retrieve the scope name of the scope indexed with iscope in parent.
+   TClassRef& cr = type_from_handle( parent );
+   if ( cr.GetClass() ) return 0;   // not supported if not at global scope
+   assert( parent == (TCppScope_t)GLOBAL_HANDLE );
+   std::string name = gClassTable->At( iscope );
+   if ( name.find("::") == std::string::npos )
+       return name;
+   return "";
 }
 
-static inline std::vector<void*> build_args(int nargs, void* args) {
-    std::vector<void*> arguments;
-    arguments.reserve(nargs);
-    for (int i = 0; i < nargs; ++i) {
-	char tc = ((CPPYY_G__value*)args)[i].type;
-        if (tc != 'a' && tc != 'o')
-            arguments.push_back(&((CPPYY_G__value*)args)[i]);
-        else
-            arguments.push_back((void*)(*(long*)&((CPPYY_G__value*)args)[i]));
-    }
-    return arguments;
+std::string Cppyy::ResolveName( const std::string& cppitem_name )
+{
+// Fully resolve the given name to the final type name.
+   std::string tclean = TClassEdit::CleanType( cppitem_name.c_str() );
+
+   TDataType* dt = gROOT->GetType( tclean.c_str() );
+   if ( dt ) return dt->GetFullTypeName();
+   return TClassEdit::ResolveTypedef( tclean.c_str(), true );
 }
 
+Cppyy::TCppScope_t Cppyy::GetScope( const std::string& sname )
+{
+   std::string scope_name;
+   if ( sname.find( "std::", 0, 5 ) == 0 )
+      scope_name = sname.substr( 5, std::string::npos );
+   else
+      scope_name = sname;
 
+   scope_name = ResolveName( scope_name );
+   auto icr = g_name2classrefidx.find( scope_name );
+   if ( icr != g_name2classrefidx.end() )
+      return (TCppType_t)icr->second;
+
+   // use TClass directly, to enable auto-loading
+   TClassRef cr( TClass::GetClass( scope_name.c_str(), kTRUE, kTRUE ) );
+   if ( !cr.GetClass() )
+      return (TCppScope_t)NULL;
+
+   // no check for ClassInfo as forward declared classes are okay (fragile)
+
+   ClassRefs_t::size_type sz = g_classrefs.size();
+   g_name2classrefidx[ scope_name ] = sz;
+   g_classrefs.push_back( TClassRef( scope_name.c_str() ) );
+   return (TCppScope_t)sz;
+}
+
+Cppyy::TCppType_t Cppyy::GetTemplate( const std::string& /* template_name */ )
+{
+   return (TCppType_t)0;
+}
+
+Cppyy::TCppType_t Cppyy::GetActualClass( TCppType_t klass, TCppObject_t obj )
+{
+   TClassRef& cr = type_from_handle( klass );
+   TClass* clActual = cr->GetActualClass( (void*)obj );
+   if ( clActual && clActual != cr.GetClass() ) {
+      // TODO: lookup through name should not be needed
+      return (TCppType_t)GetScope( clActual->GetName() );
+   }
+   return klass;
+}
+
+size_t Cppyy::SizeOf( TCppType_t klass )
+{
+   TClassRef& cr = type_from_handle( klass );
+   if ( cr.GetClass() ) return (size_t)cr->Size();
+   return (size_t)0;
+}
+
+Bool_t Cppyy::IsBuiltin( const std::string& type_name )
+{
+    TDataType* dt = gROOT->GetType( TClassEdit::CleanType( type_name.c_str(), 1 ).c_str() );
+    if ( dt ) return dt->GetType() != kOther_t;
+    return kFALSE;
+}
+
+Bool_t Cppyy::IsComplete( const std::string& type_name )
+{
+// verify whether the dictionary of this class is fully available
+   Bool_t b = kFALSE;
+
+   Int_t oldEIL = gErrorIgnoreLevel;
+   gErrorIgnoreLevel = 3000;
+   TClass* klass = TClass::GetClass( TClassEdit::ShortType( type_name.c_str(), 1 ).c_str() );
+   if ( klass && klass->GetClassInfo() )     // works for normal case w/ dict
+      b = gInterpreter->ClassInfo_IsLoaded( klass->GetClassInfo() );
+   else {      // special case for forward declared classes
+      ClassInfo_t* ci = gInterpreter->ClassInfo_Factory( type_name.c_str() );
+      if ( ci ) {
+         b = gInterpreter->ClassInfo_IsLoaded( ci );
+         gInterpreter->ClassInfo_Delete( ci );    // we own the fresh class info
+      }
+   }
+   gErrorIgnoreLevel = oldEIL;
+   return b;
+}
+
+// memory management ---------------------------------------------------------
+Cppyy::TCppObject_t Cppyy::Allocate( TCppType_t type )
+{
+   TClassRef& cr = type_from_handle( type );
+   return (TCppObject_t)malloc( cr->Size() );
+}
+
+void Cppyy::Deallocate( TCppType_t /* type */, TCppObject_t instance )
+{
+   free( instance );
+}
+
+Cppyy::TCppObject_t Cppyy::Construct( TCppType_t type )
+{
+   TClassRef& cr = type_from_handle( type );
+   return (TCppObject_t)cr->New();
+}
+
+void Cppyy::Destruct( TCppType_t type, TCppObject_t instance )
+{
+   TClassRef& cr = type_from_handle( type );
+   cr->Destructor( (void*)instance );
+}
+
+
+// method/function dispatching -----------------------------------------------
+static inline ClassInfo_t* GetGlobalNamespaceInfo()
+{
+   static ClassInfo_t* gcl = gInterpreter->ClassInfo_Factory();
+   return gcl;
+}
+
+static CallFunc_t* GetCallFunc( Cppyy::TCppMethod_t method )
+{
+   auto icf = g_method2callfunc.find( method );
+   if ( icf != g_method2callfunc.end() )
+      return icf->second;
+
+   CallFunc_t* callf = nullptr;
+   TFunction* func = (TFunction*)method;
+   std::string callString = "";
+
+// create, if not cached
+   Cppyy::TCppScope_t scope = declaring_scope( method );
+   const TClassRef& klass = type_from_handle( scope );
+   if ( klass.GetClass() || (func && scope == GLOBAL_HANDLE) ) {
+      ClassInfo_t* gcl = klass.GetClass() ? klass->GetClassInfo() : nullptr;
+      if ( ! gcl )
+         gcl = GetGlobalNamespaceInfo();
+
+      TCollection* method_args = func->GetListOfMethodArgs();
+      TIter iarg( method_args );
+
+      TMethodArg* method_arg = 0;
+      while ((method_arg = (TMethodArg*)iarg.Next())) {
+         std::string fullType = method_arg->GetTypeNormalizedName();
+         if ( callString.empty() )
+            callString = fullType;
+         else
+            callString += ", " + fullType;
+      }
+
+      Long_t offset = 0;
+      callf = gInterpreter->CallFunc_Factory();
+
+      gInterpreter->CallFunc_SetFuncProto(
+         callf,
+         gcl,
+         func ? func->GetName() : klass->GetName(),
+         callString.c_str(),
+         func ? (func->Property() & kIsConstMethod) : kFALSE,
+         &offset,
+         ROOT::kExactMatch );
+
+// CLING WORKAROUND -- The number of arguments is not always correct (e.g. when there
+//                     are default parameters, causing the callString to be wrong and
+//                     the exact match to fail); or the method may have been inline or
+//                     be compiler generated. In all those cases the exact match fails,
+//                     whereas the conversion match sometimes works.
+      if ( ! gInterpreter->CallFunc_IsValid( callf ) ) {
+         gInterpreter->CallFunc_SetFuncProto(
+            callf,
+            gcl,
+            func ? func->GetName() : klass->GetName(),
+            callString.c_str(),
+            func ? (func->Property() & kIsConstMethod) : kFALSE,
+            &offset );  // <- no kExactMatch as that will fail
+      }
+// -- CLING WORKAROUND
+
+   }
+
+   if ( !( callf && gInterpreter->CallFunc_IsValid( callf ) ) ) {
+   // TODO: propagate this error to caller w/o use of Python C-API
+   /*
+      PyErr_Format( PyExc_RuntimeError, "could not resolve %s::%s(%s)",
+         const_cast<TClassRef&>(klass).GetClassName(),
+         func ? func->GetName() : const_cast<TClassRef&>(klass).GetClassName(),
+         callString.c_str() ); */
+      std::cerr << "TODO: report unresolved function error to Python\n";
+      if ( callf ) gInterpreter->CallFunc_Delete( callf );
+      return nullptr;
+   }
+
+   g_method2callfunc[ method ] = callf;
+   return callf;
+}
+
+static inline void copy_args( void* args_, void** vargs ) {
+   std::vector<TParameter>& args = *(std::vector<TParameter>*)args_;
+   for ( std::vector<TParameter>::size_type i = 0; i < args.size(); ++i ) {
+      switch ( args[i].fTypeCode ) {
+      case 'l':          /* long */
+         vargs[i] = (void*)&args[i].fValue.fLong;
+         break;
+      case 'f':          /* double */
+         vargs[i] = (void*)&args[i].fValue.fFloat;
+         break;
+      case 'd':          /* double */
+         vargs[i] = (void*)&args[i].fValue.fDouble;
+         break;
+      case 'D':          /* long double */
+         vargs[i] = (void*)&args[i].fValue.fLongDouble;
+         break;
+      case 'k':          /* long long */
+      case 'K':          /* unsigned long long */
+      case 'U':          /* unsigned long */
+      case 'p':          /* void* */
+         vargs[i] = (void*)&args[i].fValue.fVoidp;
+         break;
+      case 'V':          /* (void*)type& */
+         vargs[i] = args[i].fValue.fVoidp;
+         break;
+      case 'r':          /* const type& */
+         vargs[i] = args[i].fRef;
+         break;
+      default:
+         std::cerr << "unknown type code: " << args[i].fTypeCode << std::endl;
+         break;
+      }
+   }
+}
+
+Bool_t FastCall(
+      Cppyy::TCppMethod_t method, void* args_, void* self, void* result )
+{
+   const std::vector<TParameter>& args = *(std::vector<TParameter>*)args_;
+
+   CallFunc_t* callf = GetCallFunc( method );
+   if ( ! callf )
+      return kFALSE;
+
+   TInterpreter::CallFuncIFacePtr_t faceptr = gCling->CallFunc_IFacePtr( callf );
+   if ( faceptr.fKind == TInterpreter::CallFuncIFacePtr_t::kGeneric ) {
+      if ( args.size() <= SMALL_ARGS_N ) {
+         void* smallbuf[SMALL_ARGS_N];
+         copy_args( args_, smallbuf );
+         faceptr.fGeneric( self, args.size(), smallbuf, result );
+      } else {
+         std::vector<void*> buf( args.size() );
+         copy_args( args_, buf.data() );
+         faceptr.fGeneric( self, args.size(), buf.data(), result );
+      }
+      return kTRUE;
+   }
+
+   if ( faceptr.fKind == TInterpreter::CallFuncIFacePtr_t::kCtor ) {
+      if ( args.size() <= SMALL_ARGS_N ) {
+         void* smallbuf[SMALL_ARGS_N];
+         copy_args( args_, (void**)smallbuf );
+         faceptr.fCtor( (void**)smallbuf, result, args.size() );
+      } else {
+         std::vector<void*> buf( args.size() );
+         copy_args( args_, buf.data() );
+         faceptr.fCtor( buf.data(), result, args.size() );
+      }
+      return kTRUE;
+   }
+
+   if ( faceptr.fKind == TInterpreter::CallFuncIFacePtr_t::kDtor ) {
+      std::cerr << " DESTRUCTOR NOT IMPLEMENTED YET! " << std::endl;
+      return kFALSE;
+   }
+
+   return kFALSE;
+}
+
+template< typename T >
+static inline T CallT( Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, void* args )
+{
+   T t{};
+   if ( FastCall( method, args, (void*)self, &t ) )
+      return t;
+   return (T)-1;
+}
+
+#define CPPYY_IMP_CALL( typecode, rtype )                                     \
+rtype Cppyy::Call##typecode( TCppMethod_t method, TCppObject_t self, void* args )\
+{                                                                            \
+   return CallT< rtype >( method, self, args );                              \
+}
+
+void Cppyy::CallV( TCppMethod_t method, TCppObject_t self, void* args )
+{
+   if ( ! FastCall( method, args, (void*)self, nullptr ) )
+      return /* TODO ... report error */;
+}
+
+CPPYY_IMP_CALL( B,  UChar_t      )
+CPPYY_IMP_CALL( C,  Char_t       )
+CPPYY_IMP_CALL( H,  Short_t      )
+CPPYY_IMP_CALL( I,  Int_t        )
+CPPYY_IMP_CALL( L,  Long_t       )
+CPPYY_IMP_CALL( LL, Long64_t     )
+CPPYY_IMP_CALL( F,  Float_t      )
+CPPYY_IMP_CALL( D,  Double_t     )
+CPPYY_IMP_CALL( LD, LongDouble_t )
+
+void* Cppyy::CallR( TCppMethod_t method, TCppObject_t self, void* args )
+{
+   void* r = nullptr;
+   if ( FastCall( method, args, (void*)self, &r ) )
+      return r;
+   return nullptr;
+}
+
+Char_t* Cppyy::CallS( TCppMethod_t method, TCppObject_t self, void* args )
+{
+   Char_t* s = nullptr;
+   if ( FastCall( method, args, (void*)self, &s ) )
+      return s;
+   return nullptr;
+}
+
+Cppyy::TCppObject_t Cppyy::CallConstructor(
+      TCppMethod_t method, TCppType_t /* klass */, void* args ) {
+   void* obj = nullptr;
+   if ( FastCall( method, args, nullptr, &obj ) )
+      return (TCppObject_t)obj;
+   return (TCppObject_t)0;
+}
+
+void Cppyy::CallDestructor( TCppType_t type, TCppObject_t self )
+{
+   TClassRef& cr = type_from_handle( type );
+   cr->Destructor( (void*)self, kTRUE );
+}
+
+Cppyy::TCppObject_t Cppyy::CallO( TCppMethod_t method,
+      TCppObject_t self, void* args, TCppType_t result_type )
+{
+   TClassRef& cr = type_from_handle( result_type );
+   void* obj = malloc( cr->Size() );
+   if ( FastCall( method, args, self, obj ) )
+      return (TCppObject_t)obj;
+   return (TCppObject_t)0;
+}
+
+Cppyy::TCppMethPtrGetter_t Cppyy::GetMethPtrGetter(
+      TCppScope_t /* scope */, TCppIndex_t /* imeth */ )
+{
+   return (TCppMethPtrGetter_t)0;
+}
+
+
+// handling of function argument buffer --------------------------------------
+void* Cppyy::AllocateFunctionArgs( size_t nargs )
+{
+   return new TParameter[nargs];
+}
+
+void Cppyy::DeallocateFunctionArgs( void* args )
+{
+   delete [] (TParameter*)args;
+}
+
+size_t Cppyy::GetFunctionArgSizeof()
+{
+   return sizeof( TParameter );
+}
+
+size_t Cppyy::GetFunctionArgTypeoffset()
+{
+   return offsetof( TParameter, fTypeCode );
+}
+
+
+// scope reflection information ----------------------------------------------
+Bool_t Cppyy::IsNamespace( TCppScope_t scope ) {
+// Test if this scope represents a namespace.
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() )
+      return cr->Property() & kIsNamespace;
+   return kFALSE;
+}
+
+Bool_t Cppyy::IsAbstract( TCppType_t klass ) {
+// Test if this type may not be instantiated.
+   TClassRef& cr = type_from_handle( klass );
+   if ( cr.GetClass() )
+      return cr->Property() & kIsAbstract;
+   return kFALSE;
+}
+
+Bool_t Cppyy::IsEnum( const std::string& type_name ) {
+   return gInterpreter->ClassInfo_IsEnum( type_name.c_str() );
+}
+
+
+// class reflection information ----------------------------------------------
+std::string Cppyy::GetFinalName( TCppType_t klass )
+{
+   if ( klass == GLOBAL_HANDLE )    // due to CLING WORKAROUND in InitConverters_
+      return "";
+   // TODO: either this or GetScopedFinalName is wrong
+   TClassRef& cr = type_from_handle( klass );
+   return cr->GetName();
+}
+
+std::string Cppyy::GetScopedFinalName( TCppType_t klass )
+{
+   // TODO: either this or GetFinalName is wrong
+   TClassRef& cr = type_from_handle( klass );
+   return cr->GetName();
+}
+
+Bool_t Cppyy::HasComplexHierarchy( TCppType_t /* handle */ )
+{
+// Always TRUE for now (pre-empts certain optimizations).
+  return kTRUE;
+}
+
+Cppyy::TCppIndex_t Cppyy::GetNumBases( TCppType_t klass )
+{
+// Get the total number of base classes that this class has.
+   TClassRef& cr = type_from_handle( klass );
+   if ( cr.GetClass() && cr->GetListOfBases() != 0 )
+      return cr->GetListOfBases()->GetSize();
+   return 0;
+}
+
+std::string Cppyy::GetBaseName( TCppType_t klass, TCppIndex_t ibase )
+{
+   TClassRef& cr = type_from_handle( klass );
+   return ((TBaseClass*)cr->GetListOfBases()->At( ibase ))->GetName();
+}
+
+Bool_t Cppyy::IsSubtype( TCppType_t derived, TCppType_t base )
+{
+   if ( derived == base )
+      return kTRUE;
+   TClassRef& derived_type = type_from_handle( derived );
+   TClassRef& base_type = type_from_handle( base );
+   return derived_type->GetBaseClass( base_type ) != 0;
+}
+
+void Cppyy::AddSmartPtrType( const std::string& type_name ) {
+   gSmartPtrTypes.insert( ResolveName( type_name ) );
+}
+
+Bool_t Cppyy::IsSmartPtr( const std::string& type_name ) {
+// checks if typename denotes a smart pointer
+// TODO: perhaps make this stricter?
+   const std::string& real_name = ResolveName( type_name );
+   return gSmartPtrTypes.find(
+      real_name.substr( 0,real_name.find( "<" ) ) ) != gSmartPtrTypes.end();
+}
+
+// type offsets --------------------------------------------------------------
+ptrdiff_t Cppyy::GetBaseOffset( TCppType_t derived, TCppType_t base,
+      TCppObject_t address, int direction, bool rerror )
+{
+// calculate offsets between declared and actual type, up-cast: direction > 0; down-cast: direction < 0
+   if ( derived == base || !(base && derived) )
+      return (ptrdiff_t)0;
+
+   TClassRef& cd = type_from_handle( derived );
+   TClassRef& cb = type_from_handle( base );
+
+   if ( !cd.GetClass() || !cb.GetClass() )
+      return (ptrdiff_t)0;
+
+   Long_t offset = -1;
+   if ( ! (cd->GetClassInfo() && cb->GetClassInfo()) ) {    // gInterpreter requirement
+   // would like to warn, but can't quite determine error from intentional
+   // hiding by developers, so only cover the case where we really should have
+   // had a class info, but apparently don't:
+      if ( cd->IsLoaded() ) {
+      // warn to allow diagnostics
+         std::ostringstream msg;
+         msg << "failed offset calculation between " << cb->GetName() << " and " << cd->GetName();
+         // TODO: propagate this warning to caller w/o use of Python C-API
+         // PyErr_Warn( PyExc_RuntimeWarning, const_cast<char*>( msg.str().c_str() ) );
+         std::cerr << "Warning: " << msg << '\n';
+      }
+
+   // return -1 to signal caller NOT to apply offset
+      return rerror ? (ptrdiff_t)offset : 0;
+   }
+
+   offset = gInterpreter->ClassInfo_GetBaseOffset(
+      cd->GetClassInfo(), cb->GetClassInfo(), (void*)address, direction > 0 );
+   if ( offset == -1 )  // Cling error, treat silently
+      return rerror ? (ptrdiff_t)offset : 0;
+
+   return (ptrdiff_t)(direction < 0 ? -offset : offset);
+}
+
+
+// method/function reflection information ------------------------------------
+Cppyy::TCppIndex_t Cppyy::GetNumMethods( TCppScope_t scope )
+{
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() && cr->GetListOfMethods() ) {
+      Cppyy::TCppIndex_t nMethods = (TCppIndex_t)cr->GetListOfMethods()->GetSize();
+      if ( nMethods == (TCppIndex_t)0 ) {
+         std::string clName = GetScopedFinalName( scope );
+         if ( clName.find( '<' ) != std::string::npos ) {
+         // chicken-and-egg problem: TClass does not know about methods until instantiation: force it
+            if ( TClass::GetClass( ("std::" + clName).c_str() ) )
+               clName = "std::" + clName;
+            std::ostringstream stmt;
+            stmt << "template class " << clName << ";";
+            gInterpreter->Declare( stmt.str().c_str() );
+         // now reload the methods
+            return (TCppIndex_t)cr->GetListOfMethods( kTRUE )->GetSize();
+         }
+      }
+      return nMethods;
+   } else if ( scope == (TCppScope_t)GLOBAL_HANDLE ) {
+   // enforce lazines by denying the existence of methods
+      return (TCppIndex_t)0;
+   }
+   return (TCppIndex_t)0;
+}
+
+Cppyy::TCppIndex_t Cppyy::GetMethodIndexAt( TCppScope_t scope, TCppIndex_t imeth)
+{
+   TClassRef& cr = type_from_handle (scope);
+   if (cr.GetClass())
+        return (TCppIndex_t)imeth;
+    assert(handle == (TCppType_t)GLOBAL_HANDLE);
+    return (TCppIndex_t)&g_globalfuncs[imeth];
+}
+
+std::vector< Cppyy::TCppMethod_t > Cppyy::GetMethodsFromName(
+      TCppScope_t scope, const std::string& name )
+{
+// TODO: this method assumes that the call for this name is made only
+// once, and thus there is no need to store the results of the search
+// in g_globalfuncs ... probably true, but needs verification
+   std::vector< TCppMethod_t > methods;
+   if ( scope == GLOBAL_HANDLE ) {
+      TCollection* funcs = gROOT->GetListOfGlobalFunctions( kTRUE );
+      g_globalfuncs.reserve(funcs->GetSize());
+
+      TIter ifunc(funcs);
+
+      TFunction* func = 0;
+      while ( (func = (TFunction*)ifunc.Next()) ) {
+      // cover not only direct matches, but also template matches
+         std::string fn = func->GetName();
+         if ( fn.rfind( name, 0 ) == 0 ) {
+         // either match exactly, or match the name as template
+            if ( (name.size() == fn.size()) ||
+                 (name.size() < fn.size() && fn[name.size()] == '<') ) {
+               methods.push_back( (TCppMethod_t)func );
+            }
+         }
+      }
+   } else {
+      TClassRef& cr = type_from_handle( scope );
+      if ( cr.GetClass() ) {
+      // todo: handle overloads
+         TMethod* m = cr->GetMethodAny( name.c_str() );
+         if ( m ) methods.push_back( (TCppMethod_t)m );
+      }
+   }
+
+   return methods;
+}
+
+Cppyy::TCppMethod_t Cppyy::GetMethod( TCppScope_t scope, TCppIndex_t imeth )
+{
+   TFunction* f = type_get_method( scope, imeth );
+   return (Cppyy::TCppMethod_t)f;
+}
+
+std::string Cppyy::GetMethodName( TCppMethod_t method )
+{
+   if ( method ) {
+      std::string name = ((TFunction*)method)->GetName();
+      //if ( IsMethodTemplate( method ) )
+      //   return name.substr( 0, name.find('<') );
+      return name;
+   }
+   return "<unknown>";
+}
+
+std::string Cppyy::GetMethodResultType( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      if ( f->ExtraProperty() & kIsConstructor )
+         return "constructor";
+      return f->GetReturnTypeNormalizedName();
+   }
+   return "<unknown>";
+}
+
+Cppyy::TCppIndex_t Cppyy::GetMethodNumArgs( TCppMethod_t method )
+{
+   if ( method )
+      return ((TFunction*)method)->GetNargs();
+   return 0;
+}
+
+Cppyy::TCppIndex_t Cppyy::GetMethodReqArgs( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      return (TCppIndex_t)(f->GetNargs() - f->GetNargsOpt());
+   }
+   return (TCppIndex_t)0;
+}
+
+std::string Cppyy::GetMethodArgName( TCppMethod_t method, int iarg )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At( iarg );
+      return arg->GetName();
+   }
+   return "<unknown>";
+}
+
+std::string Cppyy::GetMethodArgType( TCppMethod_t method, int iarg )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At( iarg );
+      return arg->GetTypeNormalizedName();
+   }
+   return "<unknown>";
+}
+
+std::string Cppyy::GetMethodArgDefault( TCppMethod_t method, int iarg )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At( iarg );
+      const char* def = arg->GetDefault();
+      if ( def )
+         return def;
+   }
+
+   return "";
+}
+
+std::string Cppyy::GetMethodSignature( TCppScope_t /* scope */, TCppIndex_t /* imeth */ )
+{
+   return "<unknown>";
+}
+
+Bool_t Cppyy::IsConstMethod( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      return f->Property() & kIsConstMethod;
+   }
+   return kFALSE;
+}
+
+
+Bool_t Cppyy::IsMethodTemplate( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      std::string name = f->GetName();
+      return (name[name.size()-1] == '>') && (name.find('<') != std::string::npos);
+   }
+   return kFALSE;
+}
+
+Cppyy::TCppIndex_t Cppyy::GetMethodNumTemplateArgs(
+      TCppScope_t /* scope */, TCppIndex_t /* imeth */ )
+{
+   return (TCppIndex_t)0;
+}
+
+std::string Cppyy::GetMethodTemplateArgName(
+      TCppScope_t /* scope */, TCppIndex_t /* imeth */, TCppIndex_t /* iarg */ )
+{
+   return "<unknown>";
+}
+
+Cppyy::TCppIndex_t Cppyy::GetGlobalOperator(
+      TCppScope_t /* scope */, TCppType_t /* lc */, TCppType_t /* rc */, const std::string& /* op */ )
+{
+   return (TCppIndex_t)0;
+}
+
+// method properties ---------------------------------------------------------
+Bool_t Cppyy::IsConstructor( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      return f->ExtraProperty() & kIsConstructor;
+   }
+   return kFALSE;
+}
+
+Bool_t Cppyy::IsPublicMethod( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      return f->Property() & kIsPublic;
+   }
+   return kFALSE;
+}
+
+Bool_t Cppyy::IsStaticMethod( TCppMethod_t method )
+{
+   if ( method ) {
+      TFunction* f = (TFunction*)method;
+      return f->Property() & kIsStatic;
+   }
+   return kFALSE;
+}
+
+// data member reflection information ----------------------------------------
+Cppyy::TCppIndex_t Cppyy::GetNumDatamembers( TCppScope_t scope )
+{
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() && cr->GetListOfDataMembers() )
+      return cr->GetListOfDataMembers()->GetSize();
+   else if ( scope == (TCppScope_t)GLOBAL_HANDLE ) {
+      std::cerr << " global data should be retrieved lazily " << std::endl;
+      TCollection* vars = gROOT->GetListOfGlobals( kTRUE );
+      if ( g_globalvars.size() != (GlobalVars_t::size_type)vars->GetSize() ) {
+         g_globalvars.clear();
+         g_globalvars.reserve(vars->GetSize());
+
+         TIter ivar(vars);
+
+         TGlobal* var = 0;
+         while ( (var = (TGlobal*)ivar.Next()) )
+            g_globalvars.push_back( var );
+      }
+      return (TCppIndex_t)g_globalvars.size();
+   }
+   return (TCppIndex_t)0;
+}
+
+std::string Cppyy::GetDatamemberName( TCppScope_t scope, TCppIndex_t idata )
+{
+   TClassRef& cr = type_from_handle( scope );
+   if (cr.GetClass()) {
+      TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+      return m->GetName();
+   }
+   assert( scope == (TCppScope_t)GLOBAL_HANDLE );
+   TGlobal* gbl = g_globalvars[ idata ];
+   return gbl->GetName();
+}
+
+std::string Cppyy::GetDatamemberType( TCppScope_t scope, TCppIndex_t idata )
+{
+   if ( scope == GLOBAL_HANDLE ) {
+      TGlobal* gbl = g_globalvars[ idata ];
+      std::string fullType = gbl->GetFullTypeName();
+      if ( fullType[fullType.size()-1] == '*' && \
+           fullType.find( "char", 0, 4 ) == std::string::npos )
+         fullType.append( "*" );
+      else if ( (int)gbl->GetArrayDim() > 1 )
+         fullType.append( "*" );
+      else if ( (int)gbl->GetArrayDim() == 1 ) {
+         std::ostringstream s;
+         s << '[' << gbl->GetMaxIndex( 0 ) << ']' << std::ends;
+         fullType.append( s.str() );
+      }
+      return fullType;
+   }
+
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() )  {
+      TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+      std::string fullType = m->GetTrueTypeName();
+      if ( (int)m->GetArrayDim() > 1 || (!m->IsBasic() && m->IsaPointer()) )
+         fullType.append( "*" );
+      else if ( (int)m->GetArrayDim() == 1 ) {
+         std::ostringstream s;
+         s << '[' << m->GetMaxIndex( 0 ) << ']' << std::ends;
+         fullType.append( s.str() );
+      }
+      return fullType;
+   }
+
+   return "<unknown>";
+}
+
+ptrdiff_t Cppyy::GetDatamemberOffset( TCppScope_t scope, TCppIndex_t idata )
+{
+   if ( scope == GLOBAL_HANDLE ) {
+      TGlobal* gbl = g_globalvars[ idata ];
+      return (ptrdiff_t)gbl->GetAddress();
+   }
+
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() ) {
+      TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+      return (ptrdiff_t)m->GetOffsetCint();      // yes, CINT ...
+   }
+
+   return (ptrdiff_t)0;
+}
+
+Cppyy::TCppIndex_t Cppyy::GetDatamemberIndex( TCppScope_t scope, const std::string& name )
+{
+   if ( scope == GLOBAL_HANDLE ) {
+      TGlobal* gb = (TGlobal*)gROOT->GetListOfGlobals( kTRUE )->FindObject( name.c_str() );
+      if ( gb && gb->GetAddress() && gb->GetAddress() != (void*)-1 ) {
+         g_globalvars.push_back( gb );
+         return g_globalvars.size() - 1;
+      }
+
+   } else {
+      TClassRef& cr = type_from_handle( scope );
+      if ( cr.GetClass() ) {
+         TDataMember* dm =
+            (TDataMember*)cr->GetListOfDataMembers()->FindObject( name.c_str() );
+         // TODO: turning this into an index is silly ...
+         if ( dm ) return (TCppIndex_t)cr->GetListOfDataMembers()->IndexOf( dm );
+      }
+   }
+
+   return (TCppIndex_t)-1;
+}
+
+
+// data member properties ----------------------------------------------------
+Bool_t Cppyy::IsPublicData( TCppScope_t scope, TCppIndex_t idata )
+{
+   if ( scope == GLOBAL_HANDLE )
+      return kTRUE;
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr->Property() & kIsNamespace )
+      return kTRUE;
+   TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+   return m->Property() & kIsPublic;
+}
+
+Bool_t Cppyy::IsStaticData( TCppScope_t scope, TCppIndex_t idata  )
+{
+   if ( scope == GLOBAL_HANDLE )
+      return kTRUE;
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr->Property() & kIsNamespace )
+      return kTRUE;
+   TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+   return m->Property() & kIsStatic;
+}
+
+Bool_t Cppyy::IsConstData( TCppScope_t scope, TCppIndex_t idata )
+{
+   if ( scope == GLOBAL_HANDLE ) {
+      TGlobal* gbl = g_globalvars[ idata ];
+      return gbl->Property() & kIsConstant;
+   }
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() ) {
+      TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+      return m->Property() & kIsConstant;
+   }
+   return kFALSE;
+}
+
+Bool_t Cppyy::IsEnumData( TCppScope_t scope, TCppIndex_t idata )
+{
+   if ( scope == GLOBAL_HANDLE ) {
+      TGlobal* gbl = g_globalvars[ idata ];
+      return gbl->Property() & kIsEnum;
+   }
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() ) {
+      TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+      return m->Property() & kIsEnum;
+   }
+   return kFALSE;
+}
+
+Int_t Cppyy::GetDimensionSize( TCppScope_t scope, TCppIndex_t idata, int dimension )
+{
+   if ( scope == GLOBAL_HANDLE ) {
+      TGlobal* gbl = g_globalvars[ idata ];
+      return gbl->GetMaxIndex( dimension );
+   }
+   TClassRef& cr = type_from_handle( scope );
+   if ( cr.GetClass() ) {
+      TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At( idata );
+      return m->GetMaxIndex( dimension );
+   }
+   return (Int_t)-1;
+}
+
+
+static inline
+std::vector<TParameter> vsargs_to_parvec(void* args, int nargs)
+{
+    std::vector<TParameter> v;
+    v.reserve(nargs);
+    for (int i=0; i<nargs; ++i)
+       v.push_back(((TParameter*)args)[i]);
+    return v;
+}
+
+//- C-linkage wrappers -------------------------------------------------------
+extern "C" {
 /* name to opaque C++ scope representation -------------------------------- */
-int cppyy_num_scopes(cppyy_scope_t handle) {
-    return 0;
+int cppyy_num_scopes(cppyy_scope_t parent) {
+    return (int)Cppyy::GetNumScopes(parent);
+}
+
+char* cppyy_scope_name(cppyy_scope_t parent, int iscope) {
+    return cppstring_to_cstring(Cppyy::GetScopeName(parent, iscope));
 }
 
 char* cppyy_resolve_name(const char* cppitem_name) {
-    std::cout << " RESOLVING: " << cppitem_name << std::endl;
-    return cppstring_to_cstring(cppitem_name);
+    return cppstring_to_cstring(Cppyy::ResolveName(cppitem_name));
 }
 
 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);
-    if (!decl) {
-        //std::string buf = TClassEdit::InsertStd(name);
-        //decl = lh.findScope(buf, &type, /* intantiateTemplate= */ true);
-    }
-    if (!decl && type) {
-        const TagType* tagtype = type->getAs<TagType>();
-        if (tagtype) {
-            decl = tagtype->getDecl();
-        }
-    }
-
-    std::cout << "FOR: " << scope_name << " RECEIVED: " << type << " AND: " << decl << std::endl;
-    if (decl) {
-        DeclContext* dc = llvm::cast<DeclContext>(const_cast<Decl*>(decl));
-        SimpleScope* s = new SimpleScope;
-        for (DeclContext::decl_iterator idecl = dc->decls_begin(); *idecl; ++idecl) {
-            if (FunctionDecl* m = llvm::dyn_cast_or_null<FunctionDecl>(*idecl))
-                s->m_methods.push_back(m);
-            else if (FieldDecl* d = llvm::dyn_cast_or_null<FieldDecl>(*idecl))
-                s->m_data.push_back(d);
-        }
-        s_scopes[(cppyy_scope_t)decl] = s;
-    }
-
-    return (cppyy_scope_t)decl;    // lookup failure return 0 (== error)
+    return cppyy_scope_t(Cppyy::GetScope(scope_name));
 }
 
+cppyy_type_t cppyy_get_template(const char* template_name) {
+    return cppyy_type_t(Cppyy::GetTemplate(template_name));
+}
+
+cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t obj) {
+    return cppyy_type_t(Cppyy::GetActualClass(klass, (void*)obj));
+}
+
+
+/* memory management ------------------------------------------------------ */
+cppyy_object_t cppyy_allocate(cppyy_type_t type) {
+    return cppyy_object_t(Cppyy::Allocate(type));
+}
+
+void cppyy_deallocate(cppyy_type_t type, cppyy_object_t self) {
+    Cppyy::Deallocate(type, (void*)self);
+}
+
+void cppyy_destruct(cppyy_type_t type, cppyy_object_t self) {
+    Cppyy::Destruct(type, (void*)self);
+}
+
 
 /* method/function dispatching -------------------------------------------- */
-
-// 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);
-// -- TODO: expect the above to live in libCling.so
-
-
-template<typename T>
-static inline T cppyy_call_T(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
-    if (s_wrappers.find(method) == s_wrappers.end()) {
-        make_wrapper((FunctionDecl*)method);
-    }
-    cling::StoredValueRef 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);
-    //    (*cb)((void*)self, nargs, const_cast<void**>(arguments.data()), ret);
-    return static_cast<T>(sv_to_long_long(ret));
+void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    Cppyy::CallV(method, (void*)self, &parvec);
 }
 
+unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (unsigned char)Cppyy::CallB(method, (void*)self, &parvec);
+}
 
+char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (char)Cppyy::CallC(method, (void*)self, &parvec);
+}
+
+short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (short)Cppyy::CallH(method, (void*)self, &parvec);
+}
 
 int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
-    return cppyy_call_T<int>(method, self, nargs, args);
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (int)Cppyy::CallI(method, (void*)self, &parvec);
 }
 
-
-
-cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t /* handle */, cppyy_index_t /* method_index */) {
-    return (cppyy_methptrgetter_t)0;
+long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* args){
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (long)Cppyy::CallL(method, (void*)self, &parvec);
 }
 
+long long cppyy_call_ll(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (long long)Cppyy::CallLL(method, (void*)self, &parvec);
+}
+
+float cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (float)Cppyy::CallF(method, (void*)self, &parvec);
+}
+
+double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (double)Cppyy::CallD(method, (void*)self, &parvec);
+}
+
+void*  cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (void*)Cppyy::CallR(method, (void*)self, &parvec);
+}
+
+char*  cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return cppstring_to_cstring(Cppyy::CallS(method, (void*)self, &parvec));
+}
+
+cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t klass, int nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return cppyy_object_t(Cppyy::CallConstructor(method, klass, &parvec));
+//    return cppyy_object_t(Cppyy::CallConstructor(method, klass, args));
+}
+
+cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void* args, cppyy_type_t result_type) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return cppyy_object_t(Cppyy::CallO(method, (void*)self, &parvec, result_type));
+}
+
+cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, cppyy_index_t idx) {
+    return cppyy_methptrgetter_t(Cppyy::GetMethPtrGetter(scope, idx));
+}
+
 
 /* handling of function argument buffer ----------------------------------- */
-void* cppyy_allocate_function_args(size_t nargs) {
-    CPPYY_G__value* args = (CPPYY_G__value*)malloc(nargs*sizeof(CPPYY_G__value));
-    for (size_t i = 0; i < nargs; ++i)
-        args[i].type = 'l';
-    return (void*)args;
+void* cppyy_allocate_function_args(int nargs){
+    return (void*)Cppyy::AllocateFunctionArgs(nargs);
 }
 
-void cppyy_deallocate_function_args(void* args) {
-    free(args);
+void cppyy_deallocate_function_args(void* args){
+    Cppyy::DeallocateFunctionArgs(args);
 }
 
-size_t cppyy_function_arg_sizeof() {
-    return sizeof(CPPYY_G__value);
+size_t cppyy_function_arg_sizeof(){
+    return (size_t)Cppyy::GetFunctionArgSizeof();
 }
 
-size_t cppyy_function_arg_typeoffset() {
-    return offsetof(CPPYY_G__value, type);
+size_t cppyy_function_arg_typeoffset(){
+    return (size_t)Cppyy::GetFunctionArgTypeoffset();
 }
 
 
 /* scope reflection information ------------------------------------------- */
-int cppyy_is_namespace(cppyy_scope_t /* handle */) {
-    return 0;
-}   
-
-int cppyy_is_enum(const char* /* type_name */) {
-    return 0;
-}
-    
-    
-/* class reflection information ------------------------------------------- */
-char* cppyy_final_name(cppyy_type_t handle) {
-    for (NamedHandles_t::iterator isp = s_named.begin(); isp != s_named.end(); ++isp) {
-        if (isp->second == (cppyy_scope_t)handle)
-            return cppstring_to_cstring(isp->first);
-    }
-    return cppstring_to_cstring("<unknown>");
+int cppyy_is_namespace(cppyy_scope_t scope) {
+    return (int)Cppyy::IsNamespace(scope);
 }
 
-char* cppyy_scoped_final_name(cppyy_type_t handle) {
-    return cppyy_final_name(handle);
-}   
-
-int cppyy_has_complex_hierarchy(cppyy_type_t /* handle */) {
-    return 1;
+int cppyy_is_enum(const char* type_name){
+    return (int)Cppyy::IsEnum(type_name);
 }
 
 
-/* method/function reflection information --------------------------------- */
-int cppyy_num_methods(cppyy_scope_t handle) {
-    SimpleScope* s = scope_from_handle(handle);
-    if (!s) return 0;
-    return s->m_methods.size();
+/* class reflection information ------------------------------------------- */
+char* cppyy_final_name(cppyy_type_t type) {
+    return cppstring_to_cstring(Cppyy::GetFinalName(type));
 }
 
-cppyy_index_t cppyy_method_index_at(cppyy_scope_t /* scope */, int imeth) {
-    return (cppyy_index_t)imeth;
+char* cppyy_scoped_final_name(cppyy_type_t type) {
+    return cppstring_to_cstring(Cppyy::GetScopedFinalName(type));
 }
 
-char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t method_index) {
-    SimpleScope* s = scope_from_handle(handle);
-    if (!s) return cppstring_to_cstring("<unknown>");
-    FunctionDecl* meth = s->m_methods.at(method_index);
-    std::cout << " METHOD NAME: " << meth->getDeclName().getAsString() << std::endl;
-    return cppstring_to_cstring(meth->getDeclName().getAsString());
+int cppyy_has_complex_hierarchy(cppyy_type_t type) {
+    return (int)Cppyy::HasComplexHierarchy(type);
 }
 
-char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t method_index) {
-    SimpleScope* s = scope_from_handle(handle);
-    if (!s) return cppstring_to_cstring("<unknown>");
-    FunctionDecl* meth = s->m_methods.at(method_index);
-    const std::string& ret_type =
-        qualtype_to_string(meth->getCallResultType(), meth->getASTContext());
-    std::cout << "    -> RET TYPE: " << ret_type << std::endl;
-    return cppstring_to_cstring(ret_type);
-}
-    
-int cppyy_method_num_args(cppyy_scope_t /* handle */, cppyy_index_t /* method_index */) {
-    return 1;
+int cppyy_num_bases(cppyy_type_t type) {
+    return (int)Cppyy::GetNumBases(type);
 }
 
-int cppyy_method_req_args(cppyy_scope_t handle, cppyy_index_t method_index) {
-    return cppyy_method_num_args(handle, method_index);
+char* cppyy_base_name(cppyy_type_t type, int base_index){
+    return cppstring_to_cstring(Cppyy::GetBaseName (type, base_index));
 }
 
-char* cppyy_method_arg_type(cppyy_scope_t /* handle */, cppyy_index_t /* method_index */, int /* arg_index */) {
-    return cppstring_to_cstring("double");
+int cppyy_is_subtype(cppyy_type_t derived, cppyy_type_t base){
+    return (int)Cppyy::IsSubtype( derived, base );
 }
 
-char* cppyy_method_arg_default(cppyy_scope_t handle, cppyy_index_t method_index, int arg_index) {
-    return cppstring_to_cstring("");
+
+/* calculate offsets between declared and actual type, up-cast: direction > 0; down-cast: direction < 0 */
+ptrdiff_t cppyy_base_offset(cppyy_type_t derived, cppyy_type_t base, cppyy_object_t address, int direction) {
+    return (ptrdiff_t)Cppyy::GetBaseOffset(derived, base, (void*)address, direction,       0);
 }
 
-char* cppyy_method_signature(cppyy_scope_t /* handle */, cppyy_index_t /* method_index */) {
-    return cppstring_to_cstring("double");
+
+/* method/function reflection information --------------------------------- */
+int cppyy_num_methods(cppyy_scope_t scope) {
+    return (int)Cppyy::GetNumMethods (scope);
 }
 
-int cppyy_method_is_template(cppyy_scope_t /* handle */, cppyy_index_t /* method_index */) {
-    return 0;
-}
-    
-cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t method_index) {
-    SimpleScope* s = scope_from_handle(handle);
-    if (!s) return (cppyy_method_t)0;
-    return (cppyy_method_t)s->m_methods.at(method_index);
+cppyy_index_t cppyy_method_index_at(cppyy_scope_t scope, int imeth) {
+    return cppyy_index_t(Cppyy::GetMethodIndexAt (scope, imeth));
 }
 
-
-/* method properties -----------------------------------------------------  */
-int cppyy_is_constructor(cppyy_type_t /* handle */, cppyy_index_t /* method_index */) {
-    return 0;
+cppyy_index_t* cppyy_method_indices_from_name(cppyy_scope_t scope, const char* name){
+//NEED TO DO:
+    return (cppyy_index_t*)0;
+//    return (cppyy_index_t*)Cppyy::GetMethodsFromName(scope, name);
 }
 
-int cppyy_is_staticmethod(cppyy_type_t /* handle */, cppyy_index_t /* method_index */) {
-    return 1;
+char* cppyy_method_name(cppyy_scope_t scope, cppyy_index_t idx) {
+    TFunction* f = type_get_method(scope, idx);
+    return cppstring_to_cstring(Cppyy::GetMethodName((Cppyy::TCppMethod_t)f));
 }
 
+char* cppyy_method_result_type(cppyy_scope_t scope, cppyy_index_t idx) {
+    TFunction* f = type_get_method(scope, idx);
+    return cppstring_to_cstring(Cppyy::GetMethodResultType((Cppyy::TCppMethod_t)f));
+}
+
+int cppyy_method_num_args(cppyy_scope_t scope, cppyy_index_t idx) {
+    TFunction* f = type_get_method(scope, idx);
+    return (int)Cppyy::GetMethodNumArgs((Cppyy::TCppMethod_t)f);
+}
+
+int cppyy_method_req_args(cppyy_scope_t scope, cppyy_index_t idx) {
+    TFunction* f = type_get_method(scope, idx);
+    return (int)Cppyy::GetMethodReqArgs((Cppyy::TCppMethod_t)f);
+}
+
+char* cppyy_method_arg_type(cppyy_scope_t scope, cppyy_index_t idx, int arg_index) {
+    TFunction* f = type_get_method(scope, idx);
+    return cppstring_to_cstring(Cppyy::GetMethodArgType((Cppyy::TCppMethod_t)f, arg_index));
+}
+
+char* cppyy_method_arg_default(cppyy_scope_t scope, cppyy_index_t idx, int arg_index) {
+    TFunction* f = type_get_method(scope, idx);
+    return cppstring_to_cstring(Cppyy::GetMethodArgDefault((Cppyy::TCppMethod_t)f, arg_index));
+}
+
+char* cppyy_method_signature(cppyy_scope_t scope, cppyy_index_t idx) {
+    return cppstring_to_cstring(Cppyy::GetMethodSignature(scope, idx));
+}
+
+int cppyy_method_is_template(cppyy_scope_t scope, cppyy_index_t idx) {
+    TFunction* f = type_get_method(scope, idx);
+    return (int)Cppyy::IsMethodTemplate((Cppyy::TCppMethod_t)f);
+}
+
+int cppyy_method_num_template_args(cppyy_scope_t scope, cppyy_index_t idx) {
+    return (int)Cppyy::GetMethodNumTemplateArgs(scope, idx);
+}
+
+char* cppyy_method_template_arg_name(cppyy_scope_t scope, cppyy_index_t idx, cppyy_index_t iarg) {
+    return cppstring_to_cstring(Cppyy::GetMethodTemplateArgName(scope, idx, iarg));
+}
+
+cppyy_method_t cppyy_get_method(cppyy_scope_t scope, cppyy_index_t idx) {
+    return cppyy_method_t(Cppyy::GetMethod(scope, idx));
+}
+
+cppyy_index_t cppyy_get_global_operator(cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char* op) {
+    return cppyy_index_t(Cppyy::GetGlobalOperator(scope, lc, rc, op));
+}
+
+
+/* method properties ------------------------------------------------------ */
+int cppyy_is_constructor(cppyy_type_t type, cppyy_index_t idx) {
+    TFunction* f = type_get_method(type, idx);
+    return (int)Cppyy::IsConstructor((Cppyy::TCppMethod_t)f);
+}
+
+int cppyy_is_staticmethod(cppyy_type_t type, cppyy_index_t idx) {
+    TFunction* f = type_get_method(type, idx);
+    return (int)Cppyy::IsStaticMethod((Cppyy::TCppMethod_t)f);
+}
+
 
 /* data member reflection information ------------------------------------- */
-int cppyy_num_datamembers(cppyy_scope_t /* handle */) {
-    return 0;
+int cppyy_num_datamembers(cppyy_scope_t scope) {
+    return (int)Cppyy::GetNumDatamembers(scope);
 }
 
+char* cppyy_datamember_name(cppyy_scope_t scope, int datamember_index) {
+    return cppstring_to_cstring(Cppyy::GetDatamemberName(scope, datamember_index));
+}
+
+char* cppyy_datamember_type(cppyy_scope_t scope, int datamember_index) {
+    return cppstring_to_cstring(Cppyy::GetDatamemberType(scope, datamember_index));
+}
+
+ptrdiff_t cppyy_datamember_offset(cppyy_scope_t scope, int datamember_index) {
+    return ptrdiff_t(Cppyy::GetDatamemberOffset(scope, datamember_index));
+}
+
+int cppyy_datamember_index(cppyy_scope_t scope, const char* name) {
+    return (int)Cppyy::GetDatamemberIndex(scope, name);
+}
+
+
+
+/* data member properties ------------------------------------------------- */
+int cppyy_is_publicdata(cppyy_type_t type, int datamember_index) {
+    return (int)Cppyy::IsPublicData(type, datamember_index);
+}
+
+int cppyy_is_staticdata(cppyy_type_t type, int datamember_index) {
+    return (int)Cppyy::IsStaticData(type, datamember_index);
+}
+
 
 /* misc helpers ----------------------------------------------------------- */
+RPY_EXTERN
+void* cppyy_load_dictionary(const char* lib_name) {
+    return (void*)(gInterpreter->Load(lib_name) == 0);
+}
+
+long long cppyy_strtoll(const char* str) {
+    return strtoll(str, NULL, 0);
+}
+
+unsigned long long cppyy_strtoull(const char* str) {
+    return strtoull(str, NULL, 0);
+}
+
 void cppyy_free(void* ptr) {
     free(ptr);
 }
 
-
-void* cppyy_load_dictionary(const char* lib_name) {
-    // TODO: need to rethink this; for now it creates reflection info from
-    //       <lib_name>.h while loading lib<lib_name>.so
-
-    // Load a library file in cling's memory.
-    // if 'system' is true, the library is never unloaded.
-    // Return 0 on success, -1 on failure.
-    // R__LOCKGUARD2(gInterpreterMutex);
-    std::cout << " NOW LOADING: " << lib_name << std::endl;


More information about the pypy-commit mailing list