Skip to content

Commit 07e91ab

Browse files
add PushTransactionRAII that works with both clang & cling
add `InstantiateFunctionDefinition` function
1 parent d85485c commit 07e91ab

File tree

5 files changed

+49
-32
lines changed

5 files changed

+49
-32
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 SynthesizingCodeRAII : public Interpreter::PushTransactionRAII {
103+
public:
104+
SynthesizingCodeRAII(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 SynthesizingCodeRAII {
386+
private:
387+
Interpreter* m_Interpreter;
388+
389+
public:
390+
SynthesizingCodeRAII(Interpreter* i) : m_Interpreter(i) {}
391+
~SynthesizingCodeRAII() {
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::SynthesizingCodeRAII 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
}
@@ -2491,23 +2497,7 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
24912497
}
24922498
if (needInstantiation) {
24932499
clang::FunctionDecl* FDmod = const_cast<clang::FunctionDecl*>(FD);
2494-
clang::Sema& S = I.getCI()->getSema();
2495-
// Could trigger deserialization of decls.
2496-
#ifdef CPPINTEROP_USE_CLING
2497-
cling::Interpreter::PushTransactionRAII RAII(&I);
2498-
#endif
2499-
S.InstantiateFunctionDefinition(SourceLocation(), FDmod,
2500-
/*Recursive=*/true,
2501-
/*DefinitionRequired=*/true);
2502-
#ifndef CPPINTEROP_USE_CLING
2503-
// TODO: Will need to replace this with a RAII for clang-repl too
2504-
auto GeneratedPTU = I.Parse("");
2505-
if (!GeneratedPTU)
2506-
llvm::logAllUnhandledErrors(
2507-
GeneratedPTU.takeError(), llvm::errs(),
2508-
"[MakeFunctionCallable -> InstantiateFunctionDefinition] Failed to "
2509-
"generate PTU:");
2510-
#endif
2500+
InstantiateFunctionDefinition(FDmod);
25112501

25122502
if (!FD->isDefined(Definition)) {
25132503
llvm::errs() << "TClingCallFunc::make_wrapper"
@@ -3313,7 +3303,8 @@ std::string ObjToString(const char* type, void* obj) {
33133303
}
33143304

33153305
static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
3316-
TemplateArgumentListInfo& TLI, Sema& S) {
3306+
TemplateArgumentListInfo& TLI, Sema& S,
3307+
bool instantiate_body) {
33173308
// This is not right but we don't have a lot of options to choose from as a
33183309
// template instantiation requires a valid source location.
33193310
SourceLocation fakeLoc = GetValidSLoc(S);
@@ -3327,6 +3318,8 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
33273318
// FIXME: Diagnose what happened.
33283319
(void)Result;
33293320
}
3321+
if (instantiate_body)
3322+
InstantiateFunctionDefinition(Specialization);
33303323
return Specialization;
33313324
}
33323325

@@ -3358,19 +3351,21 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
33583351
}
33593352

33603353
Decl* InstantiateTemplate(TemplateDecl* TemplateD,
3361-
ArrayRef<TemplateArgument> TemplateArgs, Sema& S) {
3354+
ArrayRef<TemplateArgument> TemplateArgs, Sema& S,
3355+
bool instantiate_body) {
33623356
// Create a list of template arguments.
33633357
TemplateArgumentListInfo TLI{};
33643358
for (auto TA : TemplateArgs)
33653359
TLI.addArgument(
33663360
S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()));
33673361

3368-
return InstantiateTemplate(TemplateD, TLI, S);
3362+
return InstantiateTemplate(TemplateD, TLI, S, instantiate_body);
33693363
}
33703364

33713365
TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
33723366
const TemplateArgInfo* template_args,
3373-
size_t template_args_size) {
3367+
size_t template_args_size,
3368+
bool instantiate_body) {
33743369
auto& S = I.getSema();
33753370
auto& C = S.getASTContext();
33763371

@@ -3395,14 +3390,15 @@ TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
33953390
#ifdef CPPINTEROP_USE_CLING
33963391
cling::Interpreter::PushTransactionRAII RAII(&I);
33973392
#endif
3398-
return InstantiateTemplate(TmplD, TemplateArgs, S);
3393+
return InstantiateTemplate(TmplD, TemplateArgs, S, instantiate_body);
33993394
}
34003395

34013396
TCppScope_t InstantiateTemplate(TCppScope_t tmpl,
34023397
const TemplateArgInfo* template_args,
3403-
size_t template_args_size) {
3398+
size_t template_args_size,
3399+
bool instantiate_body) {
34043400
return InstantiateTemplate(getInterp(), tmpl, template_args,
3405-
template_args_size);
3401+
template_args_size, instantiate_body);
34063402
}
34073403

34083404
void GetClassTemplateInstantiationArgs(TCppScope_t templ_instance,

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ TEST(FunctionReflectionTest, InstantiateVariadicFunction) {
905905

906906
// instantiate VariadicFnExtended
907907
auto Instance2 =
908-
Cpp::InstantiateTemplate(Decls[2], args2.data(), args2.size());
908+
Cpp::InstantiateTemplate(Decls[2], args2.data(), args2.size(), true);
909909
EXPECT_TRUE(Cpp::IsTemplatedFunction(Instance2));
910910

911911
FunctionDecl* FD2 = cast<FunctionDecl>((Decl*)Instance2);

0 commit comments

Comments
 (0)