@@ -249,23 +249,26 @@ Interpreter::~Interpreter() {
249
249
// can't find the precise resource directory in unittests so we have to hard
250
250
// code them.
251
251
const char *const Runtimes = R"(
252
- void* operator new(__SIZE_TYPE__, void* __p) noexcept;
252
+ #ifdef __cplusplus
253
253
void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
254
254
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
255
255
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
256
256
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
257
257
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
258
258
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
259
259
void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long);
260
+ struct __clang_Interpreter_NewTag{} __ci_newtag;
261
+ void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
260
262
template <class T, class = T (*)() /*disable for arrays*/>
261
263
void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
262
264
for (auto Idx = 0; Idx < Size; ++Idx)
263
- new ((void*)(((T*)Placement) + Idx)) T(Src[Idx]);
265
+ new ((void*)(((T*)Placement) + Idx), __ci_newtag ) T(Src[Idx]);
264
266
}
265
267
template <class T, unsigned long N>
266
268
void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
267
269
__clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
268
270
}
271
+ #endif // __cplusplus
269
272
)" ;
270
273
271
274
llvm::Expected<std::unique_ptr<Interpreter>>
@@ -280,7 +283,7 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
280
283
if (!PTU)
281
284
return PTU.takeError ();
282
285
283
- Interp->ValuePrintingInfo .resize (3 );
286
+ Interp->ValuePrintingInfo .resize (4 );
284
287
// FIXME: This is a ugly hack. Undo command checks its availability by looking
285
288
// at the size of the PTU list. However we have parsed something in the
286
289
// beginning of the REPL so we have to mark them as 'Irrevocable'.
@@ -501,7 +504,7 @@ Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
501
504
static constexpr llvm::StringRef MagicRuntimeInterface[] = {
502
505
" __clang_Interpreter_SetValueNoAlloc" ,
503
506
" __clang_Interpreter_SetValueWithAlloc" ,
504
- " __clang_Interpreter_SetValueCopyArr" };
507
+ " __clang_Interpreter_SetValueCopyArr" , " __ci_newtag " };
505
508
506
509
bool Interpreter::FindRuntimeInterface () {
507
510
if (llvm::all_of (ValuePrintingInfo, [](Expr *E) { return E != nullptr ; }))
@@ -531,6 +534,9 @@ bool Interpreter::FindRuntimeInterface() {
531
534
if (!LookupInterface (ValuePrintingInfo[CopyArray],
532
535
MagicRuntimeInterface[CopyArray]))
533
536
return false ;
537
+ if (!LookupInterface (ValuePrintingInfo[NewTag],
538
+ MagicRuntimeInterface[NewTag]))
539
+ return false ;
534
540
return true ;
535
541
}
536
542
@@ -608,7 +614,9 @@ class RuntimeInterfaceBuilder
608
614
.getValuePrintingInfo ()[Interpreter::InterfaceKind::CopyArray],
609
615
SourceLocation (), Args, SourceLocation ());
610
616
}
611
- Expr *Args[] = {AllocCall.get ()};
617
+ Expr *Args[] = {
618
+ AllocCall.get (),
619
+ Interp.getValuePrintingInfo ()[Interpreter::InterfaceKind::NewTag]};
612
620
ExprResult CXXNewCall = S.BuildCXXNew (
613
621
E->getSourceRange (),
614
622
/* UseGlobal=*/ true , /* PlacementLParen=*/ SourceLocation (), Args,
@@ -629,8 +637,9 @@ class RuntimeInterfaceBuilder
629
637
Interp.getValuePrintingInfo ()[Interpreter::InterfaceKind::NoAlloc],
630
638
E->getBeginLoc (), Args, E->getEndLoc ());
631
639
}
640
+ default :
641
+ llvm_unreachable (" Unhandled Interpreter::InterfaceKind" );
632
642
}
633
- llvm_unreachable (" Unhandled Interpreter::InterfaceKind" );
634
643
}
635
644
636
645
Interpreter::InterfaceKind VisitRecordType (const RecordType *Ty) {
@@ -815,3 +824,15 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
815
824
VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
816
825
VRef.setLongDouble (Val);
817
826
}
827
+
828
+ // A trampoline to work around the fact that operator placement new cannot
829
+ // really be forward declared due to libc++ and libstdc++ declaration mismatch.
830
+ // FIXME: __clang_Interpreter_NewTag is ODR violation because we get the same
831
+ // definition in the interpreter runtime. We should move it in a runtime header
832
+ // which gets included by the interpreter and here.
833
+ struct __clang_Interpreter_NewTag {};
834
+ REPL_EXTERNAL_VISIBILITY void *
835
+ operator new (size_t __sz, void *__p, __clang_Interpreter_NewTag) noexcept {
836
+ // Just forward to the standard operator placement new.
837
+ return operator new (__sz, __p);
838
+ }
0 commit comments