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
@@ -250,14 +253,9 @@ Interpreter::~Interpreter() {
250
253
// can't find the precise resource directory in unittests so we have to hard
251
254
// code them.
252
255
const char *const Runtimes = R"(
256
+ #define __CLANG_REPL__ 1
253
257
#ifdef __cplusplus
254
258
void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
255
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
256
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
257
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
258
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
259
- void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
260
- void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long);
261
259
struct __clang_Interpreter_NewTag{} __ci_newtag;
262
260
void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
263
261
template <class T, class = T (*)() /*disable for arrays*/>
@@ -269,7 +267,10 @@ const char *const Runtimes = R"(
269
267
void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
270
268
__clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
271
269
}
270
+ extern "C"
272
271
#endif // __cplusplus
272
+
273
+ void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
273
274
)" ;
274
275
275
276
llvm::Expected<std::unique_ptr<Interpreter>>
@@ -564,15 +565,17 @@ std::unique_ptr<RuntimeInterfaceBuilder> Interpreter::FindRuntimeInterface() {
564
565
if (!LookupInterface (ValuePrintingInfo[NoAlloc],
565
566
MagicRuntimeInterface[NoAlloc]))
566
567
return nullptr ;
567
- if (!LookupInterface (ValuePrintingInfo[WithAlloc],
568
- MagicRuntimeInterface[WithAlloc]))
569
- return nullptr ;
570
- if (!LookupInterface (ValuePrintingInfo[CopyArray],
571
- MagicRuntimeInterface[CopyArray]))
572
- return nullptr ;
573
- if (!LookupInterface (ValuePrintingInfo[NewTag],
574
- MagicRuntimeInterface[NewTag]))
575
- return nullptr ;
568
+ if (Ctx.getLangOpts ().CPlusPlus ) {
569
+ if (!LookupInterface (ValuePrintingInfo[WithAlloc],
570
+ MagicRuntimeInterface[WithAlloc]))
571
+ return nullptr ;
572
+ if (!LookupInterface (ValuePrintingInfo[CopyArray],
573
+ MagicRuntimeInterface[CopyArray]))
574
+ return nullptr ;
575
+ if (!LookupInterface (ValuePrintingInfo[NewTag],
576
+ MagicRuntimeInterface[NewTag]))
577
+ return nullptr ;
578
+ }
576
579
577
580
return createInProcessRuntimeInterfaceBuilder (*this , Ctx, S);
578
581
}
@@ -831,69 +834,82 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal,
831
834
return VRef.getPtr ();
832
835
}
833
836
834
- // Pointers, lvalue struct that can take as a reference.
835
- REPL_EXTERNAL_VISIBILITY void
836
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
837
- void *Val) {
838
- Value &VRef = *(Value *)OutVal;
839
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
840
- VRef.setPtr (Val);
841
- }
842
-
843
- REPL_EXTERNAL_VISIBILITY void
844
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal,
845
- void *OpaqueType) {
837
+ REPL_EXTERNAL_VISIBILITY
838
+ extern " C" void __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal,
839
+ void *OpaqueType, ...) {
846
840
Value &VRef = *(Value *)OutVal;
847
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
848
- }
849
-
850
- static void SetValueDataBasedOnQualType (Value &V, unsigned long long Data) {
851
- QualType QT = V.getType ();
852
- if (const auto *ET = QT->getAs <EnumType>())
853
- QT = ET->getDecl ()->getIntegerType ();
854
-
855
- switch (QT->castAs <BuiltinType>()->getKind ()) {
856
- default :
857
- llvm_unreachable (" unknown type kind!" );
858
- #define X (type, name ) \
859
- case BuiltinType::name: \
860
- V.set ##name (Data); \
861
- break ;
862
- REPL_BUILTIN_TYPES
863
- #undef X
841
+ Interpreter *I = static_cast <Interpreter *>(This);
842
+ VRef = Value (I, OpaqueType);
843
+ if (VRef.isVoid ())
844
+ return ;
845
+
846
+ va_list args;
847
+ va_start (args, /* last named param*/ OpaqueType);
848
+
849
+ QualType QT = VRef.getType ();
850
+ if (VRef.getKind () == Value::K_PtrOrObj) {
851
+ VRef.setPtr (va_arg (args, void *));
852
+ } else {
853
+ if (const auto *ET = QT->getAs <EnumType>())
854
+ QT = ET->getDecl ()->getIntegerType ();
855
+ switch (QT->castAs <BuiltinType>()->getKind ()) {
856
+ default :
857
+ llvm_unreachable (" unknown type kind!" );
858
+ break ;
859
+ // Types shorter than int are resolved as int, else va_arg has UB.
860
+ case BuiltinType::Bool:
861
+ VRef.setBool (va_arg (args, int ));
862
+ break ;
863
+ case BuiltinType::Char_S:
864
+ VRef.setChar_S (va_arg (args, int ));
865
+ break ;
866
+ case BuiltinType::SChar:
867
+ VRef.setSChar (va_arg (args, int ));
868
+ break ;
869
+ case BuiltinType::Char_U:
870
+ VRef.setChar_U (va_arg (args, unsigned ));
871
+ break ;
872
+ case BuiltinType::UChar:
873
+ VRef.setUChar (va_arg (args, unsigned ));
874
+ break ;
875
+ case BuiltinType::Short:
876
+ VRef.setShort (va_arg (args, int ));
877
+ break ;
878
+ case BuiltinType::UShort:
879
+ VRef.setUShort (va_arg (args, unsigned ));
880
+ break ;
881
+ case BuiltinType::Int:
882
+ VRef.setInt (va_arg (args, int ));
883
+ break ;
884
+ case BuiltinType::UInt:
885
+ VRef.setUInt (va_arg (args, unsigned ));
886
+ break ;
887
+ case BuiltinType::Long:
888
+ VRef.setLong (va_arg (args, long ));
889
+ break ;
890
+ case BuiltinType::ULong:
891
+ VRef.setULong (va_arg (args, unsigned long ));
892
+ break ;
893
+ case BuiltinType::LongLong:
894
+ VRef.setLongLong (va_arg (args, long long ));
895
+ break ;
896
+ case BuiltinType::ULongLong:
897
+ VRef.setULongLong (va_arg (args, unsigned long long ));
898
+ break ;
899
+ // Types shorter than double are resolved as double, else va_arg has UB.
900
+ case BuiltinType::Float:
901
+ VRef.setFloat (va_arg (args, double ));
902
+ break ;
903
+ case BuiltinType::Double:
904
+ VRef.setDouble (va_arg (args, double ));
905
+ break ;
906
+ case BuiltinType::LongDouble:
907
+ VRef.setLongDouble (va_arg (args, long double ));
908
+ break ;
909
+ // See REPL_BUILTIN_TYPES.
910
+ }
864
911
}
865
- }
866
-
867
- REPL_EXTERNAL_VISIBILITY void
868
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
869
- unsigned long long Val) {
870
- Value &VRef = *(Value *)OutVal;
871
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
872
- SetValueDataBasedOnQualType (VRef, Val);
873
- }
874
-
875
- REPL_EXTERNAL_VISIBILITY void
876
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
877
- float Val) {
878
- Value &VRef = *(Value *)OutVal;
879
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
880
- VRef.setFloat (Val);
881
- }
882
-
883
- REPL_EXTERNAL_VISIBILITY void
884
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
885
- double Val) {
886
- Value &VRef = *(Value *)OutVal;
887
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
888
- VRef.setDouble (Val);
889
- }
890
-
891
- REPL_EXTERNAL_VISIBILITY void
892
- __clang_Interpreter_SetValueNoAlloc (void *This, void *OutVal, void *OpaqueType,
893
- long double Val) {
894
- Value &VRef = *(Value *)OutVal;
895
- VRef = Value (static_cast <Interpreter *>(This), OpaqueType);
896
- VRef.setLongDouble (Val);
912
+ va_end (args);
897
913
}
898
914
899
915
// A trampoline to work around the fact that operator placement new cannot
0 commit comments