@@ -250,23 +250,26 @@ Interpreter::~Interpreter() {
250
250
// can't find the precise resource directory in unittests so we have to hard
251
251
// code them.
252
252
const char *const Runtimes = R"(
253
- void* operator new(__SIZE_TYPE__, void* __p) noexcept;
253
+ #ifdef __cplusplus
254
254
void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
255
255
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
256
256
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
257
257
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
258
258
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
259
259
void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
260
260
void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long);
261
+ struct __clang_Interpreter_NewTag{} __ci_newtag;
262
+ void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
261
263
template <class T, class = T (*)() /*disable for arrays*/>
262
264
void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
263
265
for (auto Idx = 0; Idx < Size; ++Idx)
264
- new ((void*)(((T*)Placement) + Idx)) T(Src[Idx]);
266
+ new ((void*)(((T*)Placement) + Idx), __ci_newtag ) T(Src[Idx]);
265
267
}
266
268
template <class T, unsigned long N>
267
269
void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
268
270
__clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
269
271
}
272
+ #endif // __cplusplus
270
273
)" ;
271
274
272
275
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'.
@@ -497,7 +500,7 @@ Interpreter::CompileDtorCall(CXXRecordDecl *CXXRD) {
497
500
static constexpr llvm::StringRef MagicRuntimeInterface[] = {
498
501
" __clang_Interpreter_SetValueNoAlloc" ,
499
502
" __clang_Interpreter_SetValueWithAlloc" ,
500
- " __clang_Interpreter_SetValueCopyArr" };
503
+ " __clang_Interpreter_SetValueCopyArr" , " __ci_newtag " };
501
504
502
505
bool Interpreter::FindRuntimeInterface () {
503
506
if (llvm::all_of (ValuePrintingInfo, [](Expr *E) { return E != nullptr ; }))
@@ -527,6 +530,9 @@ bool Interpreter::FindRuntimeInterface() {
527
530
if (!LookupInterface (ValuePrintingInfo[CopyArray],
528
531
MagicRuntimeInterface[CopyArray]))
529
532
return false ;
533
+ if (!LookupInterface (ValuePrintingInfo[NewTag],
534
+ MagicRuntimeInterface[NewTag]))
535
+ return false ;
530
536
return true ;
531
537
}
532
538
@@ -604,7 +610,9 @@ class RuntimeInterfaceBuilder
604
610
.getValuePrintingInfo ()[Interpreter::InterfaceKind::CopyArray],
605
611
SourceLocation (), Args, SourceLocation ());
606
612
}
607
- Expr *Args[] = {AllocCall.get ()};
613
+ Expr *Args[] = {
614
+ AllocCall.get (),
615
+ Interp.getValuePrintingInfo ()[Interpreter::InterfaceKind::NewTag]};
608
616
ExprResult CXXNewCall = S.BuildCXXNew (
609
617
E->getSourceRange (),
610
618
/* UseGlobal=*/ true , /* PlacementLParen=*/ SourceLocation (), Args,
@@ -625,8 +633,9 @@ class RuntimeInterfaceBuilder
625
633
Interp.getValuePrintingInfo ()[Interpreter::InterfaceKind::NoAlloc],
626
634
E->getBeginLoc (), Args, E->getEndLoc ());
627
635
}
636
+ default :
637
+ llvm_unreachable (" Unhandled Interpreter::InterfaceKind" );
628
638
}
629
- llvm_unreachable (" Unhandled Interpreter::InterfaceKind" );
630
639
}
631
640
632
641
Interpreter::InterfaceKind VisitRecordType (const RecordType *Ty) {
@@ -811,3 +820,15 @@ __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
811
820
VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
812
821
VRef.setLongDouble (Val);
813
822
}
823
+
824
+ // A trampoline to work around the fact that operator placement new cannot
825
+ // really be forward declared due to libc++ and libstdc++ declaration mismatch.
826
+ // FIXME: __clang_Interpreter_NewTag is ODR violation because we get the same
827
+ // definition in the interpreter runtime. We should move it in a runtime header
828
+ // which gets included by the interpreter and here.
829
+ struct __clang_Interpreter_NewTag {};
830
+ REPL_EXTERNAL_VISIBILITY void *
831
+ operator new (size_t __sz, void *__p, __clang_Interpreter_NewTag) noexcept {
832
+ // Just forward to the standard operator placement new.
833
+ return operator new (__sz, __p);
834
+ }
0 commit comments