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