Skip to content

Commit 35b6780

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

File tree

4 files changed

+48
-31
lines changed

4 files changed

+48
-31
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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ namespace compat {
9999

100100
using Interpreter = cling::Interpreter;
101101

102+
class PushTransactionRAII : public Interpreter::PushTransactionRAII {
103+
PushTransactionRAII(Interpreter* i) : Interpreter::PushTransactionRAII(i) {}
104+
};
105+
102106
inline void maybeMangleDeclName(const clang::GlobalDecl& GD,
103107
std::string& mangledName) {
104108
cling::utils::Analyze::maybeMangleDeclName(GD, mangledName);
@@ -376,6 +380,20 @@ namespace Cpp_utils = Cpp::utils;
376380

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

381399
#endif // CPPINTEROP_USE_REPL

lib/CppInterOp/CppInterOp.cpp

Lines changed: 26 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,16 @@ 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+
(void)Cpp::Interpreter::CompilationResult();
233+
}
234+
}
235+
225236
bool IsAggregate(TCppScope_t scope) {
226237
Decl* D = static_cast<Decl*>(scope);
227238

@@ -923,11 +934,7 @@ TCppType_t GetFunctionReturnType(TCppFunction_t func) {
923934
}
924935

925936
if (needInstantiation) {
926-
#ifdef CPPINTEROP_USE_CLING
927-
cling::Interpreter::PushTransactionRAII RAII(&getInterp());
928-
#endif
929-
getSema().InstantiateFunctionDefinition(SourceLocation(), FD, true,
930-
true);
937+
InstantiateFunctionDefinition(FD);
931938
}
932939
Type = FD->getReturnType();
933940
}
@@ -2482,23 +2489,7 @@ int get_wrapper_code(compat::Interpreter& I, const FunctionDecl* FD,
24822489
}
24832490
if (needInstantiation) {
24842491
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
2492+
InstantiateFunctionDefinition(FDmod);
25022493

25032494
if (!FD->isDefined(Definition)) {
25042495
llvm::errs() << "TClingCallFunc::make_wrapper"
@@ -3304,7 +3295,8 @@ std::string ObjToString(const char* type, void* obj) {
33043295
}
33053296

33063297
static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
3307-
TemplateArgumentListInfo& TLI, Sema& S) {
3298+
TemplateArgumentListInfo& TLI, Sema& S,
3299+
bool instantiate_body) {
33083300
// This is not right but we don't have a lot of options to choose from as a
33093301
// template instantiation requires a valid source location.
33103302
SourceLocation fakeLoc = GetValidSLoc(S);
@@ -3318,6 +3310,8 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
33183310
// FIXME: Diagnose what happened.
33193311
(void)Result;
33203312
}
3313+
if (instantiate_body)
3314+
InstantiateFunctionDefinition(Specialization);
33213315
return Specialization;
33223316
}
33233317

@@ -3349,19 +3343,21 @@ static Decl* InstantiateTemplate(TemplateDecl* TemplateD,
33493343
}
33503344

33513345
Decl* InstantiateTemplate(TemplateDecl* TemplateD,
3352-
ArrayRef<TemplateArgument> TemplateArgs, Sema& S) {
3346+
ArrayRef<TemplateArgument> TemplateArgs, Sema& S,
3347+
bool instantiate_body) {
33533348
// Create a list of template arguments.
33543349
TemplateArgumentListInfo TLI{};
33553350
for (auto TA : TemplateArgs)
33563351
TLI.addArgument(
33573352
S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()));
33583353

3359-
return InstantiateTemplate(TemplateD, TLI, S);
3354+
return InstantiateTemplate(TemplateD, TLI, S, instantiate_body);
33603355
}
33613356

33623357
TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
33633358
const TemplateArgInfo* template_args,
3364-
size_t template_args_size) {
3359+
size_t template_args_size,
3360+
bool instantiate_body) {
33653361
auto& S = I.getSema();
33663362
auto& C = S.getASTContext();
33673363

@@ -3386,14 +3382,15 @@ TCppScope_t InstantiateTemplate(compat::Interpreter& I, TCppScope_t tmpl,
33863382
#ifdef CPPINTEROP_USE_CLING
33873383
cling::Interpreter::PushTransactionRAII RAII(&I);
33883384
#endif
3389-
return InstantiateTemplate(TmplD, TemplateArgs, S);
3385+
return InstantiateTemplate(TmplD, TemplateArgs, S, instantiate_body);
33903386
}
33913387

33923388
TCppScope_t InstantiateTemplate(TCppScope_t tmpl,
33933389
const TemplateArgInfo* template_args,
3394-
size_t template_args_size) {
3390+
size_t template_args_size,
3391+
bool instantiate_body) {
33953392
return InstantiateTemplate(getInterp(), tmpl, template_args,
3396-
template_args_size);
3393+
template_args_size, instantiate_body);
33973394
}
33983395

33993396
void GetClassTemplateInstantiationArgs(TCppScope_t templ_instance,

0 commit comments

Comments
 (0)