42
42
#include " llvm/Support/ErrorHandling.h"
43
43
#include " llvm/Support/raw_ostream.h"
44
44
#include " llvm/TargetParser/Host.h"
45
+
46
+ #include < cstdarg>
47
+
45
48
using namespace clang ;
46
49
47
50
// FIXME: Figure out how to unify with namespace init_convenience from
@@ -270,14 +273,10 @@ Interpreter::~Interpreter() {
270
273
// can't find the precise resource directory in unittests so we have to hard
271
274
// code them.
272
275
const char *const Runtimes = R"(
276
+ #define __CLANG_REPL__ 1
273
277
#ifdef __cplusplus
278
+ #define EXTERN_C extern "C"
274
279
void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
275
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
276
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
277
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
278
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
279
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
280
- void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long);
281
280
struct __clang_Interpreter_NewTag{} __ci_newtag;
282
281
void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
283
282
template <class T, class = T (*)() /*disable for arrays*/>
@@ -289,7 +288,11 @@ const char *const Runtimes = R"(
289
288
void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
290
289
__clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
291
290
}
291
+ #else
292
+ #define EXTERN_C extern
292
293
#endif // __cplusplus
294
+
295
+ EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
293
296
)" ;
294
297
295
298
llvm::Expected<std::unique_ptr<Interpreter>>
@@ -588,15 +591,17 @@ std::unique_ptr<RuntimeInterfaceBuilder> Interpreter::FindRuntimeInterface() {
588
591
if (!LookupInterface (ValuePrintingInfo[NoAlloc],
589
592
MagicRuntimeInterface[NoAlloc]))
590
593
return nullptr ;
591
- if (!LookupInterface (ValuePrintingInfo[WithAlloc],
592
- MagicRuntimeInterface[WithAlloc]))
593
- return nullptr ;
594
- if (!LookupInterface (ValuePrintingInfo[CopyArray],
595
- MagicRuntimeInterface[CopyArray]))
596
- return nullptr ;
597
- if (!LookupInterface (ValuePrintingInfo[NewTag],
598
- MagicRuntimeInterface[NewTag]))
599
- return nullptr ;
594
+ if (Ctx.getLangOpts ().CPlusPlus ) {
595
+ if (!LookupInterface (ValuePrintingInfo[WithAlloc],
596
+ MagicRuntimeInterface[WithAlloc]))
597
+ return nullptr ;
598
+ if (!LookupInterface (ValuePrintingInfo[CopyArray],
599
+ MagicRuntimeInterface[CopyArray]))
600
+ return nullptr ;
601
+ if (!LookupInterface (ValuePrintingInfo[NewTag],
602
+ MagicRuntimeInterface[NewTag]))
603
+ return nullptr ;
604
+ }
600
605
601
606
return createInProcessRuntimeInterfaceBuilder (*this , Ctx, S);
602
607
}
@@ -855,69 +860,81 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal,
855
860
return VRef.getPtr ();
856
861
}
857
862
858
- // Pointers, lvalue struct that can take as a reference.
859
- REPL_EXTERNAL_VISIBILITY void
860
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
861
- void *Val) {
863
+ extern " C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc (
864
+ void *This, void *OutVal, void *OpaqueType, ...) {
862
865
Value &VRef = *(Value *)OutVal;
863
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
864
- VRef.setPtr (Val);
865
- }
866
+ Interpreter *I = static_cast <Interpreter *>(This);
867
+ VRef = Value (I, OpaqueType);
868
+ if (VRef.isVoid ())
869
+ return ;
866
870
867
- REPL_EXTERNAL_VISIBILITY void
868
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal,
869
- void *OpaqueType) {
870
- Value &VRef = *(Value *)OutVal;
871
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
872
- }
871
+ va_list args;
872
+ va_start (args, /* last named param*/ OpaqueType);
873
873
874
- static void SetValueDataBasedOnQualType (Value &V, unsigned long long Data) {
875
- QualType QT = V.getType ();
876
- if (const auto *ET = QT->getAs <EnumType>())
877
- QT = ET->getDecl ()->getIntegerType ();
878
-
879
- switch (QT->castAs <BuiltinType>()->getKind ()) {
880
- default :
881
- llvm_unreachable (" unknown type kind!" );
882
- #define X (type, name ) \
883
- case BuiltinType::name: \
884
- V.set ##name (Data); \
885
- break ;
886
- REPL_BUILTIN_TYPES
887
- #undef X
874
+ QualType QT = VRef.getType ();
875
+ if (VRef.getKind () == Value::K_PtrOrObj) {
876
+ VRef.setPtr (va_arg (args, void *));
877
+ } else {
878
+ if (const auto *ET = QT->getAs <EnumType>())
879
+ QT = ET->getDecl ()->getIntegerType ();
880
+ switch (QT->castAs <BuiltinType>()->getKind ()) {
881
+ default :
882
+ llvm_unreachable (" unknown type kind!" );
883
+ break ;
884
+ // Types shorter than int are resolved as int, else va_arg has UB.
885
+ case BuiltinType::Bool:
886
+ VRef.setBool (va_arg (args, int ));
887
+ break ;
888
+ case BuiltinType::Char_S:
889
+ VRef.setChar_S (va_arg (args, int ));
890
+ break ;
891
+ case BuiltinType::SChar:
892
+ VRef.setSChar (va_arg (args, int ));
893
+ break ;
894
+ case BuiltinType::Char_U:
895
+ VRef.setChar_U (va_arg (args, unsigned ));
896
+ break ;
897
+ case BuiltinType::UChar:
898
+ VRef.setUChar (va_arg (args, unsigned ));
899
+ break ;
900
+ case BuiltinType::Short:
901
+ VRef.setShort (va_arg (args, int ));
902
+ break ;
903
+ case BuiltinType::UShort:
904
+ VRef.setUShort (va_arg (args, unsigned ));
905
+ break ;
906
+ case BuiltinType::Int:
907
+ VRef.setInt (va_arg (args, int ));
908
+ break ;
909
+ case BuiltinType::UInt:
910
+ VRef.setUInt (va_arg (args, unsigned ));
911
+ break ;
912
+ case BuiltinType::Long:
913
+ VRef.setLong (va_arg (args, long ));
914
+ break ;
915
+ case BuiltinType::ULong:
916
+ VRef.setULong (va_arg (args, unsigned long ));
917
+ break ;
918
+ case BuiltinType::LongLong:
919
+ VRef.setLongLong (va_arg (args, long long ));
920
+ break ;
921
+ case BuiltinType::ULongLong:
922
+ VRef.setULongLong (va_arg (args, unsigned long long ));
923
+ break ;
924
+ // Types shorter than double are resolved as double, else va_arg has UB.
925
+ case BuiltinType::Float:
926
+ VRef.setFloat (va_arg (args, double ));
927
+ break ;
928
+ case BuiltinType::Double:
929
+ VRef.setDouble (va_arg (args, double ));
930
+ break ;
931
+ case BuiltinType::LongDouble:
932
+ VRef.setLongDouble (va_arg (args, long double ));
933
+ break ;
934
+ // See REPL_BUILTIN_TYPES.
935
+ }
888
936
}
889
- }
890
-
891
- REPL_EXTERNAL_VISIBILITY void
892
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
893
- unsigned long long Val) {
894
- Value &VRef = *(Value *)OutVal;
895
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
896
- SetValueDataBasedOnQualType (VRef, Val);
897
- }
898
-
899
- REPL_EXTERNAL_VISIBILITY void
900
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
901
- float Val) {
902
- Value &VRef = *(Value *)OutVal;
903
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
904
- VRef.setFloat (Val);
905
- }
906
-
907
- REPL_EXTERNAL_VISIBILITY void
908
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
909
- double Val) {
910
- Value &VRef = *(Value *)OutVal;
911
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
912
- VRef.setDouble (Val);
913
- }
914
-
915
- REPL_EXTERNAL_VISIBILITY void
916
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
917
- long double Val) {
918
- Value &VRef = *(Value *)OutVal;
919
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
920
- VRef.setLongDouble (Val);
937
+ va_end (args);
921
938
}
922
939
923
940
// A trampoline to work around the fact that operator placement new cannot
0 commit comments