"Use other ctor with dtor decls!" assertion

I end up with GlobalDecl.h:33: void clang::GlobalDecl::Init(const clang::Decl*): Assertion `!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"' failed. when invoking “getAddressOfGlobal” in the loop below for a destructor (similarly for constructors):

  cling::Transaction* tp = 0;
  auto const dcr = cling->declare("#include <string>;\n ...", &tp);
  if (cling::Interpreter::kSuccess != dcr) return;
  assert(tp);
  for (auto dg = tp->decls_begin(); dg != tp->decls_end(); ++dg) {
    if (!dg->m_DGR.isSingleDecl()) continue;
    auto fd = llvm::dyn_cast<clang::FunctionDecl>(dg->m_DGR.getSingleDecl());
    if (!fd) continue;
    auto fn = fd->getNameAsString();
    bool from_jit = false;
    void* fm = cling->getAddressOfGlobal(fd, &from_jit);
    ...
  }

How can i tell when a FunctionDecl is a ctor/dtor? (In my case these are ~basic_string and basic_string, not JIT-ed symbols, and i am not interested in them, so skipping getAddressOfGlobal() would be fine.)

Hi,

You can try to cast to (using dyn_cast(fd)) or check for (using isa(fd)) CXXConstructorDecl / CXXDestructorDecl. See clang.llvm.org/doxygen/classclan … dDecl.html

Cheers, Axel.

Thanks, isa() works like a charm!

The next step is: how can I expose JIT-ed member functions to the static code? Is the only way wrapping the them in a global function (and passing a pointer to the object), or is there some nicer/cleaner workaround?

Hi,

Going through C functions (that you could build through parsing C++ code, building AST nodes or building llvm IR) is indeed the safest way. If you can rely on a given calling convention you can try to get the symbol’s address and set up the stack accordingly. I’d not do that, though - I would parse code unless you have really good reasons not to do that.

Cheers, Axel.