clang 18.0.0git
Value.h
Go to the documentation of this file.
1//===--- Value.h - Definition of interpreter value --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Value is a lightweight struct that is used for carrying execution results in
10// clang-repl. It's a special runtime that acts like a messager between compiled
11// code and interpreted code. This makes it possible to exchange interesting
12// information between the compiled & interpreted world.
13//
14// A typical usage is like the below:
15//
16// Value V;
17// Interp.ParseAndExecute("int x = 42;");
18// Interp.ParseAndExecute("x", &V);
19// V.getType(); // <-- Yields a clang::QualType.
20// V.getInt(); // <-- Yields 42.
21//
22// The current design is still highly experimental and nobody should rely on the
23// API being stable because we're hopefully going to make significant changes to
24// it in the relatively near future. For example, Value also intends to be used
25// as an exchange token for JIT support enabling remote execution on the embed
26// devices where the JIT infrastructure cannot fit. To support that we will need
27// to split the memory storage in a different place and perhaps add a resource
28// header is similar to intrinsics headers which have stricter performance
29// constraints.
30//
31//===----------------------------------------------------------------------===//
32
33#ifndef LLVM_CLANG_INTERPRETER_VALUE_H
34#define LLVM_CLANG_INTERPRETER_VALUE_H
35
36#include "llvm/Support/Compiler.h"
37#include <cstdint>
38
39// NOTE: Since the REPL itself could also include this runtime, extreme caution
40// should be taken when MAKING CHANGES to this file, especially when INCLUDE NEW
41// HEADERS, like <string>, <memory> and etc. (That pulls a large number of
42// tokens and will impact the runtime performance of the REPL)
43
44namespace llvm {
45class raw_ostream;
46
47} // namespace llvm
48
49namespace clang {
50
51class ASTContext;
52class Interpreter;
53class QualType;
54
55#if defined(_WIN32)
56// REPL_EXTERNAL_VISIBILITY are symbols that we need to be able to locate
57// at runtime. On Windows, this requires them to be exported from any of the
58// modules loaded at runtime. Marking them as dllexport achieves this; both
59// for DLLs (that normally export symbols as part of their interface) and for
60// EXEs (that normally don't export anything).
61// For a build with libclang-cpp.dll, this doesn't make any difference - the
62// functions would have been exported anyway. But for cases when these are
63// statically linked into an EXE, it makes sure that they're exported.
64#define REPL_EXTERNAL_VISIBILITY __declspec(dllexport)
65#elif __has_attribute(visibility)
66#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
67#define REPL_EXTERNAL_VISIBILITY __attribute__((visibility("default")))
68#else
69#define REPL_EXTERNAL_VISIBILITY
70#endif
71#else
72#define REPL_EXTERNAL_VISIBILITY
73#endif
74
75#define REPL_BUILTIN_TYPES \
76 X(bool, Bool) \
77 X(char, Char_S) \
78 X(signed char, SChar) \
79 X(unsigned char, UChar) \
80 X(short, Short) \
81 X(unsigned short, UShort) \
82 X(int, Int) \
83 X(unsigned int, UInt) \
84 X(long, Long) \
85 X(unsigned long, ULong) \
86 X(long long, LongLong) \
87 X(unsigned long long, ULongLong) \
88 X(float, Float) \
89 X(double, Double) \
90 X(long double, LongDouble)
91
93 union Storage {
94#define X(type, name) type m_##name;
96#undef X
97 void *m_Ptr;
98 };
99
100public:
101 enum Kind {
102#define X(type, name) K_##name,
104#undef X
105
108 K_Unspecified
109 };
110
111 Value() = default;
112 Value(Interpreter *In, void *Ty);
113 Value(const Value &RHS);
114 Value(Value &&RHS) noexcept;
115 Value &operator=(const Value &RHS);
116 Value &operator=(Value &&RHS) noexcept;
117 ~Value();
118
119 void printType(llvm::raw_ostream &Out) const;
120 void printData(llvm::raw_ostream &Out) const;
121 void print(llvm::raw_ostream &Out) const;
122 void dump() const;
123 void clear();
124
125 ASTContext &getASTContext();
126 const ASTContext &getASTContext() const;
127 Interpreter &getInterpreter();
128 const Interpreter &getInterpreter() const;
129 QualType getType() const;
130
131 bool isValid() const { return ValueKind != K_Unspecified; }
132 bool isVoid() const { return ValueKind == K_Void; }
133 bool hasValue() const { return isValid() && !isVoid(); }
134 bool isManuallyAlloc() const { return IsManuallyAlloc; }
135 Kind getKind() const { return ValueKind; }
136 void setKind(Kind K) { ValueKind = K; }
137 void setOpaqueType(void *Ty) { OpaqueType = Ty; }
138
139 void *getPtr() const;
140 void setPtr(void *Ptr) { Data.m_Ptr = Ptr; }
141
142#define X(type, name) \
143 void set##name(type Val) { Data.m_##name = Val; } \
144 type get##name() const { return Data.m_##name; }
146#undef X
147
148 /// \brief Get the value with cast.
149 //
150 /// Get the value cast to T. This is similar to reinterpret_cast<T>(value),
151 /// casting the value of builtins (except void), enums and pointers.
152 /// Values referencing an object are treated as pointers to the object.
153 template <typename T> T convertTo() const {
154 return convertFwd<T>::cast(*this);
155 }
156
157protected:
158 bool isPointerOrObjectType() const { return ValueKind == K_PtrOrObj; }
159
160 /// \brief Get to the value with type checking casting the underlying
161 /// stored value to T.
162 template <typename T> T as() const {
163 switch (ValueKind) {
164 default:
165 return T();
166#define X(type, name) \
167 case Value::K_##name: \
168 return (T)Data.m_##name;
170#undef X
171 }
172 }
173
174 // Allow convertTo to be partially specialized.
175 template <typename T> struct convertFwd {
176 static T cast(const Value &V) {
177 if (V.isPointerOrObjectType())
178 return (T)(uintptr_t)V.as<void *>();
179 if (!V.isValid() || V.isVoid()) {
180 return T();
181 }
182 return V.as<T>();
183 }
184 };
185
186 template <typename T> struct convertFwd<T *> {
187 static T *cast(const Value &V) {
188 if (V.isPointerOrObjectType())
189 return (T *)(uintptr_t)V.as<void *>();
190 return nullptr;
191 }
192 };
193
194 Interpreter *Interp = nullptr;
195 void *OpaqueType = nullptr;
196 Storage Data;
197 Kind ValueKind = K_Unspecified;
198 bool IsManuallyAlloc = false;
199};
200
201template <> inline void *Value::as() const {
203 return Data.m_Ptr;
204 return (void *)as<uintptr_t>();
205}
206
207} // namespace clang
208#endif
#define V(N, I)
Definition: ASTContext.h:3233
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &, QualType)
Definition: InterpFrame.cpp:89
#define REPL_EXTERNAL_VISIBILITY
Definition: Value.h:72
#define REPL_BUILTIN_TYPES
Definition: Value.h:75
const char * Data
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Provides top-level interfaces for incremental compilation and execution.
Definition: Interpreter.h:76
A (possibly-)qualified type.
Definition: Type.h:736
bool isManuallyAlloc() const
Definition: Value.h:134
void setKind(Kind K)
Definition: Value.h:136
bool isPointerOrObjectType() const
Definition: Value.h:158
REPL_BUILTIN_TYPES T convertTo() const
Get the value with cast.
Definition: Value.h:153
T as() const
Get to the value with type checking casting the underlying stored value to T.
Definition: Value.h:162
Value()=default
bool isValid() const
Definition: Value.h:131
void setOpaqueType(void *Ty)
Definition: Value.h:137
void setPtr(void *Ptr)
Definition: Value.h:140
@ K_PtrOrObj
Definition: Value.h:107
bool hasValue() const
Definition: Value.h:133
Kind getKind() const
Definition: Value.h:135
Storage Data
Definition: Value.h:196
bool isVoid() const
Definition: Value.h:132
YAML serialization mapping.
Definition: Dominators.h:30
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
static T * cast(const Value &V)
Definition: Value.h:187
static T cast(const Value &V)
Definition: Value.h:176