Skip to content

Commit 16ae2e9

Browse files
add PushTransactionRAII that works with both clang & cling
add `InstantiateFunctionDefinition` function
1 parent 5103dca commit 16ae2e9

File tree

5 files changed

+51
-34
lines changed

5 files changed

+51
-34
lines changed

include/CppInterOp/CppInterOp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,11 +743,12 @@ struct TemplateArgInfo {
743743
/// in the \c TemplateArgInfo struct
744744
///\param[in] template_args_size - Size of the vector of template arguments
745745
/// passed as \c template_args
746+
///\param[in] instantiate_body - also instantiate/define the body
746747
///
747748
///\returns Instantiated templated class/function/variable pointer
748749
CPPINTEROP_API TCppScope_t
749750
InstantiateTemplate(TCppScope_t tmpl, const TemplateArgInfo* template_args,
750-
size_t template_args_size);
751+
size_t template_args_size, bool instantiate_body = false);
751752

752753
/// Sets the class template instantiation arguments of \c templ_instance.
753754
///

lib/CppInterOp/CXCppInterOp.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,8 @@ bool clang_existsFunctionTemplate(const char* name, CXScope parent) {
571571
namespace Cpp {
572572
TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
573573
const TemplateArgInfo* template_args,
574-
size_t template_args_size);
574+
size_t template_args_size,
575+
bool instantiate_body = false);
575576
} // namespace Cpp
576577

577578
CXScope clang_instantiateTemplate(CXScope tmpl,

lib/CppInterOp/Compatibility.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ namespace compat {
9999

100100
using Interpreter = cling::Interpreter;
101101

102+
class PushTransactionRAII : public Interpreter::PushTransactionRAII {
103+
public:
104+
PushTransactionRAII(Interpreter* i) : Interpreter::PushTransactionRAII(i) {}
105+
};
106+
102107
inline void maybeMangleDeclName(const clang::GlobalDecl& GD,
103108
std::string& mangledName) {
104109
cling::utils::Analyze::maybeMangleDeclName(GD, mangledName);
@@ -376,6 +381,20 @@ namespace Cpp_utils = Cpp::utils;
376381

377382
namespace compat {
378383
using Interpreter = Cpp::Interpreter;
384+
385+
class PushTransactionRAII {
386+
private:
387+
Interpreter* m_Interpreter;
388+
389+
public:
390+
PushTransactionRAII(Interpreter* i) : m_Interpreter(i) {}
391+
~PushTransactionRAII() {
392+
auto GeneratedPTU = m_Interpreter->Parse("");
393+
if (!GeneratedPTU)
394+
llvm::logAllUnhandledErrors(GeneratedPTU.takeError(), llvm::errs(),
395+
"Failed to generate PTU:");
396+
}
397+
};
379398
}
380399

381400
#endif // CPPINTEROP_USE_REPL

lib/CppInterOp/CppInterOp.cpp

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "clang/Basic/Specifiers.h"
3434
#include "clang/Basic/Version.h"
3535
#include "clang/Frontend/CompilerInstance.h"
36+
#include "clang/Interpreter/Interpreter.h"
3637
#include "clang/Sema/Lookup.h"
3738
#include "clang/Sema/Overload.h"
3839
#include "clang/Sema/Ownership.h"
@@ -222,6 +223,15 @@ void EnableDebugOutput(bool value /* =true*/) { llvm::DebugFlag = value; }
222223

223224
bool IsDebugOutputEnabled() { return llvm::DebugFlag; }
224225

226+
static void InstantiateFunctionDefinition(Decl* D) {
227+
compat::PushTransactionRAII RAII(&getInterp());
228+
if (auto* FD = llvm::dyn_cast_or_null<FunctionDecl>(D)) {
229+
getSema().InstantiateFunctionDefinition(SourceLocation(), FD,
230+
/*Recursive=*/true,
231+
/*DefinitionRequired=*/true);
232+
}
233+
}
234+
225235
bool IsAggregate(TCppScope_t scope) {
226236
Decl* D = static_cast<Decl*>(scope);
227237

@@ -923,11 +933,7 @@ TCppType_t GetFunctionReturnType(TCppFunction_t func) {
923933
}
924934

925935
if (needInstantiation) {
926-
#ifdef CPPINTEROP_USE_CLING
927-
cling::Interpreter::PushTransactionRAII RAII(&getInterp());
928-
#endif
929-
getSema().InstantiateFunctionDefinition(SourceLocation(), FD, true,
930-
true);
936+
InstantiateFunctionDefinition(FD);
931937
}
932938
Type = FD->getReturnType();
933939
}
@@ -2482,23 +2488,7 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
24822488
}
24832489
if (needInstantiation) {
24842490
clang::FunctionDecl* FDmod = const_cast<clang::FunctionDecl*>(FD);
2485-
clang::Sema& S = I.getCI()->getSema();
2486-
// Could trigger deserialization of decls.
2487-
#ifdef CPPINTEROP_USE_CLING
2488-
cling::Interpreter::PushTransactionRAII RAII(&I);
2489-
#endif
2490-
S.InstantiateFunctionDefinition(SourceLocation(), FDmod,
2491-
/*Recursive=*/true,
2492-
/*DefinitionRequired=*/true);
2493-
#ifndef CPPINTEROP_USE_CLING
2494-
// TODO: Will need to replace this with a RAII for clang-repl too
2495-
auto GeneratedPTU = I.Parse("");
2496-
if (!GeneratedPTU)
2497-
llvm::logAllUnhandledErrors(
2498-
GeneratedPTU.takeError(), llvm::errs(),
2499-
"[MakeFunctionCallable -> InstantiateFunctionDefinition] Failed to "
2500-
"generate PTU:");
2501-
#endif
2491+
InstantiateFunctionDefinition(FDmod);
25022492

25032493
if (!FD->isDefined(Definition)) {
25042494
llvm::errs() << "TClingCallFunc::make_wrapper"
@@ -3304,7 +3294,8 @@ std::string ObjToString(const char* type, void* obj) {
33043294
}
33053295

33063296
static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
3307-
TemplateArgumentListInfo& TLI, Sema& S) {
3297+
TemplateArgumentListInfo& TLI, Sema& S,
3298+
bool instantiate_body) {
33083299
// This is not right but we don't have a lot of options to choose from as a
33093300
// template instantiation requires a valid source location.
33103301
SourceLocation fakeLoc = GetValidSLoc(S);
@@ -3318,6 +3309,8 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
33183309
// FIXME: Diagnose what happened.
33193310
(void)Result;
33203311
}
3312+
if (instantiate_body)
3313+
InstantiateFunctionDefinition(Specialization);
33213314
return Specialization;
33223315
}
33233316

@@ -3349,19 +3342,21 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
33493342
}
33503343

33513344
Decl* InstantiateTemplate(TemplateDecl* TemplateD,
3352-
ArrayRef<TemplateArgument> TemplateArgs, Sema& S) {
3345+
ArrayRef<TemplateArgument> TemplateArgs, Sema& S,
3346+
bool instantiate_body) {
33533347
// Create a list of template arguments.
33543348
TemplateArgumentListInfo TLI{};
33553349
for (auto TA : TemplateArgs)
33563350
TLI.addArgument(
33573351
S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()));
33583352

3359-
return InstantiateTemplate(TemplateD, TLI, S);
3353+
return InstantiateTemplate(TemplateD, TLI, S, instantiate_body);
33603354
}
33613355

33623356
TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
33633357
const TemplateArgInfo* template_args,
3364-
size_t template_args_size) {
3358+
size_t template_args_size,
3359+
bool instantiate_body) {
33653360
auto& S = I.getSema();
33663361
auto& C = S.getASTContext();
33673362

@@ -3386,14 +3381,15 @@ TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
33863381
#ifdef CPPINTEROP_USE_CLING
33873382
cling::Interpreter::PushTransactionRAII RAII(&I);
33883383
#endif
3389-
return InstantiateTemplate(TmplD, TemplateArgs, S);
3384+
return InstantiateTemplate(TmplD, TemplateArgs, S, instantiate_body);
33903385
}
33913386

33923387
TCppScope_t InstantiateTemplate(TCppScope_t tmpl,
33933388
const TemplateArgInfo* template_args,
3394-
size_t template_args_size) {
3389+
size_t template_args_size,
3390+
bool instantiate_body) {
33953391
return InstantiateTemplate(getInterp(), tmpl, template_args,
3396-
template_args_size);
3392+
template_args_size, instantiate_body);
33973393
}
33983394

33993395
void GetClassTemplateInstantiationArgs(TCppScope_t templ_instance,

unittests/CppInterOp/VariableReflectionTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,9 @@ TEST(VariableReflectionTest, StaticConstExprDatamember) {
559559
std::vector<Cpp::TemplateArgInfo> template_args = {
560560
{C.IntTy.getAsOpaquePtr(), "5"}};
561561

562-
Cpp::TCppFunction_t MyTemplatedClass =
563-
Cpp::InstantiateTemplate(Cpp::GetNamed("MyTemplatedClass"),
564-
template_args.data(), template_args.size());
562+
Cpp::TCppFunction_t MyTemplatedClass = Cpp::InstantiateTemplate(
563+
Cpp::GetNamed("MyTemplatedClass"), template_args.data(),
564+
template_args.size(), true);
565565
EXPECT_TRUE(MyTemplatedClass);
566566

567567
datamembers.clear();

0 commit comments

Comments
 (0)