File indexing completed on 2026-05-10 08:36:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #ifndef LLVM_CLANG_INTERPRETER_VALUE_H
0034 #define LLVM_CLANG_INTERPRETER_VALUE_H
0035
0036 #include "llvm/Config/llvm-config.h" // for LLVM_BUILD_LLVM_DYLIB, LLVM_BUILD_SHARED_LIBS
0037 #include "llvm/Support/Compiler.h"
0038 #include <cstdint>
0039
0040
0041
0042
0043
0044
0045 namespace llvm {
0046 class raw_ostream;
0047
0048 }
0049
0050 namespace clang {
0051
0052 class ASTContext;
0053 class Interpreter;
0054 class QualType;
0055
0056 #if defined(_WIN32)
0057
0058
0059
0060
0061
0062
0063
0064
0065 #define REPL_EXTERNAL_VISIBILITY __declspec(dllexport)
0066 #elif __has_attribute(visibility)
0067 #if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
0068 #define REPL_EXTERNAL_VISIBILITY __attribute__((visibility("default")))
0069 #else
0070 #define REPL_EXTERNAL_VISIBILITY
0071 #endif
0072 #else
0073 #define REPL_EXTERNAL_VISIBILITY
0074 #endif
0075
0076 #define REPL_BUILTIN_TYPES \
0077 X(bool, Bool) \
0078 X(char, Char_S) \
0079 X(signed char, SChar) \
0080 X(unsigned char, Char_U) \
0081 X(unsigned char, UChar) \
0082 X(short, Short) \
0083 X(unsigned short, UShort) \
0084 X(int, Int) \
0085 X(unsigned int, UInt) \
0086 X(long, Long) \
0087 X(unsigned long, ULong) \
0088 X(long long, LongLong) \
0089 X(unsigned long long, ULongLong) \
0090 X(float, Float) \
0091 X(double, Double) \
0092 X(long double, LongDouble)
0093
0094 class REPL_EXTERNAL_VISIBILITY Value {
0095 union Storage {
0096 #define X(type, name) type m_##name;
0097 REPL_BUILTIN_TYPES
0098 #undef X
0099 void *m_Ptr;
0100 };
0101
0102 public:
0103 enum Kind {
0104 #define X(type, name) K_##name,
0105 REPL_BUILTIN_TYPES
0106 #undef X
0107
0108 K_Void,
0109 K_PtrOrObj,
0110 K_Unspecified
0111 };
0112
0113 Value() = default;
0114 Value(Interpreter *In, void *Ty);
0115 Value(const Value &RHS);
0116 Value(Value &&RHS) noexcept;
0117 Value &operator=(const Value &RHS);
0118 Value &operator=(Value &&RHS) noexcept;
0119 ~Value();
0120
0121 void printType(llvm::raw_ostream &Out) const;
0122 void printData(llvm::raw_ostream &Out) const;
0123 void print(llvm::raw_ostream &Out) const;
0124 void dump() const;
0125 void clear();
0126
0127 ASTContext &getASTContext();
0128 const ASTContext &getASTContext() const;
0129 Interpreter &getInterpreter();
0130 const Interpreter &getInterpreter() const;
0131 QualType getType() const;
0132
0133 bool isValid() const { return ValueKind != K_Unspecified; }
0134 bool isVoid() const { return ValueKind == K_Void; }
0135 bool hasValue() const { return isValid() && !isVoid(); }
0136 bool isManuallyAlloc() const { return IsManuallyAlloc; }
0137 Kind getKind() const { return ValueKind; }
0138 void setKind(Kind K) { ValueKind = K; }
0139 void setOpaqueType(void *Ty) { OpaqueType = Ty; }
0140
0141 void *getPtr() const;
0142 void setPtr(void *Ptr) { Data.m_Ptr = Ptr; }
0143
0144 #define X(type, name) \
0145 void set##name(type Val) { Data.m_##name = Val; } \
0146 type get##name() const { return Data.m_##name; }
0147 REPL_BUILTIN_TYPES
0148 #undef X
0149
0150
0151
0152
0153
0154
0155 template <typename T> T convertTo() const {
0156 return convertFwd<T>::cast(*this);
0157 }
0158
0159 protected:
0160 bool isPointerOrObjectType() const { return ValueKind == K_PtrOrObj; }
0161
0162
0163
0164 template <typename T> T as() const {
0165 switch (ValueKind) {
0166 default:
0167 return T();
0168 #define X(type, name) \
0169 case Value::K_##name: \
0170 return (T)Data.m_##name;
0171 REPL_BUILTIN_TYPES
0172 #undef X
0173 }
0174 }
0175
0176
0177 template <typename T> struct convertFwd {
0178 static T cast(const Value &V) {
0179 if (V.isPointerOrObjectType())
0180 return (T)(uintptr_t)V.as<void *>();
0181 if (!V.isValid() || V.isVoid()) {
0182 return T();
0183 }
0184 return V.as<T>();
0185 }
0186 };
0187
0188 template <typename T> struct convertFwd<T *> {
0189 static T *cast(const Value &V) {
0190 if (V.isPointerOrObjectType())
0191 return (T *)(uintptr_t)V.as<void *>();
0192 return nullptr;
0193 }
0194 };
0195
0196 Interpreter *Interp = nullptr;
0197 void *OpaqueType = nullptr;
0198 Storage Data;
0199 Kind ValueKind = K_Unspecified;
0200 bool IsManuallyAlloc = false;
0201 };
0202
0203 template <> inline void *Value::as() const {
0204 if (isPointerOrObjectType())
0205 return Data.m_Ptr;
0206 return (void *)as<uintptr_t>();
0207 }
0208
0209 }
0210 #endif