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