clang  19.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 
44 namespace llvm {
45 class raw_ostream;
46 
47 } // namespace llvm
48 
49 namespace clang {
50 
51 class ASTContext;
52 class Interpreter;
53 class 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, Char_U) \
80  X(unsigned char, UChar) \
81  X(short, Short) \
82  X(unsigned short, UShort) \
83  X(int, Int) \
84  X(unsigned int, UInt) \
85  X(long, Long) \
86  X(unsigned long, ULong) \
87  X(long long, LongLong) \
88  X(unsigned long long, ULongLong) \
89  X(float, Float) \
90  X(double, Double) \
91  X(long double, LongDouble)
92 
94  union Storage {
95 #define X(type, name) type m_##name;
97 #undef X
98  void *m_Ptr;
99  };
100 
101 public:
102  enum Kind {
103 #define X(type, name) K_##name,
105 #undef X
106 
109  K_Unspecified
110  };
111 
112  Value() = default;
113  Value(Interpreter *In, void *Ty);
114  Value(const Value &RHS);
115  Value(Value &&RHS) noexcept;
116  Value &operator=(const Value &RHS);
117  Value &operator=(Value &&RHS) noexcept;
118  ~Value();
119 
120  void printType(llvm::raw_ostream &Out) const;
121  void printData(llvm::raw_ostream &Out) const;
122  void print(llvm::raw_ostream &Out) const;
123  void dump() const;
124  void clear();
125 
126  ASTContext &getASTContext();
127  const ASTContext &getASTContext() const;
128  Interpreter &getInterpreter();
129  const Interpreter &getInterpreter() const;
130  QualType getType() const;
131 
132  bool isValid() const { return ValueKind != K_Unspecified; }
133  bool isVoid() const { return ValueKind == K_Void; }
134  bool hasValue() const { return isValid() && !isVoid(); }
135  bool isManuallyAlloc() const { return IsManuallyAlloc; }
136  Kind getKind() const { return ValueKind; }
137  void setKind(Kind K) { ValueKind = K; }
138  void setOpaqueType(void *Ty) { OpaqueType = Ty; }
139 
140  void *getPtr() const;
141  void setPtr(void *Ptr) { Data.m_Ptr = Ptr; }
142 
143 #define X(type, name) \
144  void set##name(type Val) { Data.m_##name = Val; } \
145  type get##name() const { return Data.m_##name; }
147 #undef X
148 
149  /// \brief Get the value with cast.
150  //
151  /// Get the value cast to T. This is similar to reinterpret_cast<T>(value),
152  /// casting the value of builtins (except void), enums and pointers.
153  /// Values referencing an object are treated as pointers to the object.
154  template <typename T> T convertTo() const {
155  return convertFwd<T>::cast(*this);
156  }
157 
158 protected:
159  bool isPointerOrObjectType() const { return ValueKind == K_PtrOrObj; }
160 
161  /// \brief Get to the value with type checking casting the underlying
162  /// stored value to T.
163  template <typename T> T as() const {
164  switch (ValueKind) {
165  default:
166  return T();
167 #define X(type, name) \
168  case Value::K_##name: \
169  return (T)Data.m_##name;
171 #undef X
172  }
173  }
174 
175  // Allow convertTo to be partially specialized.
176  template <typename T> struct convertFwd {
177  static T cast(const Value &V) {
178  if (V.isPointerOrObjectType())
179  return (T)(uintptr_t)V.as<void *>();
180  if (!V.isValid() || V.isVoid()) {
181  return T();
182  }
183  return V.as<T>();
184  }
185  };
186 
187  template <typename T> struct convertFwd<T *> {
188  static T *cast(const Value &V) {
189  if (V.isPointerOrObjectType())
190  return (T *)(uintptr_t)V.as<void *>();
191  return nullptr;
192  }
193  };
194 
195  Interpreter *Interp = nullptr;
196  void *OpaqueType = nullptr;
198  Kind ValueKind = K_Unspecified;
199  bool IsManuallyAlloc = false;
200 };
201 
202 template <> inline void *Value::as() const {
203  if (isPointerOrObjectType())
204  return Data.m_Ptr;
205  return (void *)as<uintptr_t>();
206 }
207 
208 } // namespace clang
209 #endif
#define V(N, I)
Definition: ASTContext.h:3299
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, QualType Ty)
#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:185
Provides top-level interfaces for incremental compilation and execution.
Definition: Interpreter.h:91
A (possibly-)qualified type.
Definition: Type.h:940
bool isManuallyAlloc() const
Definition: Value.h:135
void setKind(Kind K)
Definition: Value.h:137
bool isPointerOrObjectType() const
Definition: Value.h:159
REPL_BUILTIN_TYPES T convertTo() const
Get the value with cast.
Definition: Value.h:154
T as() const
Get to the value with type checking casting the underlying stored value to T.
Definition: Value.h:163
Value()=default
bool isValid() const
Definition: Value.h:132
void setOpaqueType(void *Ty)
Definition: Value.h:138
void setPtr(void *Ptr)
Definition: Value.h:141
@ K_PtrOrObj
Definition: Value.h:108
bool hasValue() const
Definition: Value.h:134
Kind getKind() const
Definition: Value.h:136
Storage Data
Definition: Value.h:197
bool isVoid() const
Definition: Value.h:133
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Definition: Address.h:291
Diagnostic wrappers for TextAPI types for error reporting.
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:188
static T cast(const Value &V)
Definition: Value.h:177