Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/CppInterOp/CppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ CPPINTEROP_API std::string GetVersion();
///\returns the demangled representation of the given mangled_name
CPPINTEROP_API std::string Demangle(const std::string& mangled_name);

///\returns the mangled representation of the given scope
CPPINTEROP_API std::string MangledNameOf(TCppScope_t scope);

/// Enables or disables the debugging printouts on stderr.
/// Debugging output can be enabled also by the environment variable
/// CPPINTEROP_EXTRA_INTERPRETER_ARGS. For example,
Expand All @@ -353,6 +356,9 @@ CPPINTEROP_API bool IsClass(TCppScope_t scope);
/// Checks if the scope is a function.
CPPINTEROP_API bool IsFunction(TCppScope_t scope);

/// Checks if the scope is an inline function.
CPPINTEROP_API bool IsInlineFunction(TCppScope_t scope);

/// Checks if the type is a function pointer.
CPPINTEROP_API bool IsFunctionPointerType(TCppType_t type);

Expand Down Expand Up @@ -622,6 +628,10 @@ CPPINTEROP_API bool IsStaticMethod(TCppConstFunction_t method);
/// Checks if the provided constructor or conversion operator is explicit
CPPINTEROP_API bool IsExplicit(TCppConstFunction_t method);

/// Gets the LLVM module (IR) for the given scope
CPPINTEROP_API std::string GetLLVMMouleFor(TCppScope_t scope,
TInterp_t Interp = nullptr);

///\returns the address of the function given its potentially mangled name.
CPPINTEROP_API TCppFuncAddr_t GetFunctionAddress(const char* mangled_name);

Expand Down
3 changes: 3 additions & 0 deletions include/CppInterOp/Dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ extern "C" CPPINTEROP_API CppFnPtrTy CppGetProcAddress(const char* procname);
DISPATCH_API(GetClassTemplateInstantiationArgs, \
decltype(&CppImpl::GetClassTemplateInstantiationArgs)) \
DISPATCH_API(IsClass, decltype(&CppImpl::IsClass)) \
DISPATCH_API(IsInlineFunction, decltype(&CppImpl::IsInlineFunction)) \
DISPATCH_API(MangledNameOf, decltype(&CppImpl::MangledNameOf)) \
DISPATCH_API(GetType, decltype(&CppImpl::GetType)) \
DISPATCH_API(GetTypeFromScope, decltype(&CppImpl::GetTypeFromScope)) \
DISPATCH_API(GetComplexType, decltype(&CppImpl::GetComplexType)) \
Expand Down Expand Up @@ -185,6 +187,7 @@ extern "C" CPPINTEROP_API CppFnPtrTy CppGetProcAddress(const char* procname);
decltype(&CppImpl::BeginStdStreamCapture)) \
DISPATCH_API(GetDoxygenComment, decltype(&CppImpl::GetDoxygenComment)) \
DISPATCH_API(IsExplicit, decltype(&CppImpl::IsExplicit)) \
DISPATCH_API(GetLLVMMouleFor, decltype(&CppImpl::GetLLVMMouleFor)) \
DISPATCH_API(MakeFunctionCallable, \
CppImpl::JitCall (*)(CppImpl::TCppConstFunction_t)) \
DISPATCH_API(GetFunctionAddress, \
Expand Down
41 changes: 41 additions & 0 deletions lib/CppInterOp/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,27 @@ static compat::Interpreter& getInterp(TInterp_t I = nullptr) {
static clang::Sema& getSema() { return getInterp().getCI()->getSema(); }
static clang::ASTContext& getASTContext() { return getSema().getASTContext(); }

std::string GetLLVMMouleFor(TCppScope_t scope, TInterp_t Interp) {
auto* D = static_cast<clang::Decl*>(scope);
auto& I = getInterp(Interp);

ASTContext& C = I.getSema().getASTContext();

D->addAttr(UsedAttr::CreateImplicit(C));
I.getCI()->getASTConsumer().HandleTopLevelDecl(DeclGroupRef(D));

// FIXME: We parse and create a PTU but don't send it to JIT. Is this safe?
auto GeneratedPTU = I.Parse("");
if (!GeneratedPTU)
return "";

std::string ModuleCode;
llvm::raw_string_ostream OS(ModuleCode);
GeneratedPTU->TheModule->print(OS, nullptr);
OS.flush();
return ModuleCode;
}

static void ForceCodeGen(Decl* D, compat::Interpreter& I) {
// The decl was deferred by CodeGen. Force its emission.
// FIXME: In ASTContext::DeclMustBeEmitted we should check if the
Expand Down Expand Up @@ -352,6 +373,12 @@ bool IsFunction(TCppScope_t scope) {
return isa<FunctionDecl>(D);
}

bool IsInlineFunction(TCppScope_t scope) {
Decl* D = static_cast<Decl*>(scope);
return isa<FunctionDecl>(D) &&
llvm::dyn_cast<FunctionDecl>(D)->isInlineSpecified();
}

bool IsFunctionPointerType(TCppType_t type) {
QualType QT = QualType::getFromOpaquePtr(type);
return QT->isFunctionPointerType();
Expand Down Expand Up @@ -1427,6 +1454,20 @@ TCppFuncAddr_t GetFunctionAddress(const char* mangled_name) {
return nullptr;
}

std::string MangledNameOf(TCppScope_t scope) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is that different from maybeMangleDeclName?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are the same, I guess. Will change the implementation of this function to just call maybeMangleDeclName.

auto* D = static_cast<Decl*>(scope);
if (auto* FD = llvm::dyn_cast_or_null<FunctionDecl>(D)) {
auto* MangleCtxt = getASTContext().createMangleContext();
std::string mangled_name;
llvm::raw_string_ostream ostream(mangled_name);
MangleCtxt->mangleName(FD, ostream);
ostream.flush();
delete MangleCtxt;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead [cppcoreguidelines-owning-memory]

    delete MangleCtxt;
    ^
Additional context

lib/CppInterOp/CppInterOp.cpp:1459: variable declared here

    auto* MangleCtxt = getASTContext().createMangleContext();
    ^

return mangled_name;
}
return "";
}

static TCppFuncAddr_t GetFunctionAddress(const FunctionDecl* FD) {
const auto get_mangled_name = [](const FunctionDecl* FD) {
auto MangleCtxt = getASTContext().createMangleContext();
Expand Down
Loading