File indexing completed on 2026-05-10 08:36:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
0015 #define LLVM_CLANG_INTERPRETER_INTERPRETER_H
0016
0017 #include "clang/AST/GlobalDecl.h"
0018 #include "clang/Interpreter/PartialTranslationUnit.h"
0019 #include "clang/Interpreter/Value.h"
0020
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ExecutionEngine/JITSymbol.h"
0023 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
0024 #include "llvm/Support/Error.h"
0025 #include <memory>
0026 #include <vector>
0027
0028 namespace llvm {
0029 namespace orc {
0030 class LLJIT;
0031 class LLJITBuilder;
0032 class ThreadSafeContext;
0033 }
0034 }
0035
0036 namespace clang {
0037
0038 class CompilerInstance;
0039 class CodeGenerator;
0040 class CXXRecordDecl;
0041 class Decl;
0042 class IncrementalExecutor;
0043 class IncrementalParser;
0044 class IncrementalCUDADeviceParser;
0045
0046
0047 class IncrementalCompilerBuilder {
0048 public:
0049 IncrementalCompilerBuilder() {}
0050
0051 void SetCompilerArgs(const std::vector<const char *> &Args) {
0052 UserArgs = Args;
0053 }
0054
0055 void SetTargetTriple(std::string TT) { TargetTriple = TT; }
0056
0057
0058 llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCpp();
0059
0060
0061 void SetOffloadArch(llvm::StringRef Arch) { OffloadArch = Arch; };
0062
0063
0064 void SetCudaSDK(llvm::StringRef path) { CudaSDKPath = path; };
0065
0066 llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaHost();
0067 llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaDevice();
0068
0069 private:
0070 static llvm::Expected<std::unique_ptr<CompilerInstance>>
0071 create(std::string TT, std::vector<const char *> &ClangArgv);
0072
0073 llvm::Expected<std::unique_ptr<CompilerInstance>> createCuda(bool device);
0074
0075 std::vector<const char *> UserArgs;
0076 std::optional<std::string> TargetTriple;
0077
0078 llvm::StringRef OffloadArch;
0079 llvm::StringRef CudaSDKPath;
0080 };
0081
0082 class IncrementalAction;
0083 class InProcessPrintingASTConsumer;
0084
0085
0086 class Interpreter {
0087 friend class Value;
0088 friend InProcessPrintingASTConsumer;
0089
0090 std::unique_ptr<llvm::orc::ThreadSafeContext> TSCtx;
0091
0092 std::unique_ptr<IncrementalAction> Act;
0093 std::unique_ptr<IncrementalParser> IncrParser;
0094 std::unique_ptr<IncrementalExecutor> IncrExecutor;
0095
0096
0097 std::unique_ptr<IncrementalCUDADeviceParser> DeviceParser;
0098
0099
0100 std::unique_ptr<IncrementalAction> DeviceAct;
0101
0102
0103 std::list<PartialTranslationUnit> PTUs;
0104
0105 unsigned InitPTUSize = 0;
0106
0107
0108
0109
0110 Value LastValue;
0111
0112
0113
0114 std::unique_ptr<llvm::Module> CachedInCodeGenModule;
0115
0116
0117 std::unique_ptr<CompilerInstance> CI;
0118
0119
0120 std::unique_ptr<CompilerInstance> DeviceCI;
0121
0122 protected:
0123
0124 Interpreter(std::unique_ptr<CompilerInstance> Instance, llvm::Error &Err,
0125 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr,
0126 std::unique_ptr<clang::ASTConsumer> Consumer = nullptr);
0127
0128
0129
0130 llvm::Error CreateExecutor();
0131
0132
0133
0134 void ResetExecutor();
0135
0136 public:
0137 virtual ~Interpreter();
0138 static llvm::Expected<std::unique_ptr<Interpreter>>
0139 create(std::unique_ptr<CompilerInstance> CI);
0140 static llvm::Expected<std::unique_ptr<Interpreter>>
0141 createWithCUDA(std::unique_ptr<CompilerInstance> CI,
0142 std::unique_ptr<CompilerInstance> DCI);
0143 const ASTContext &getASTContext() const;
0144 ASTContext &getASTContext();
0145 const CompilerInstance *getCompilerInstance() const;
0146 CompilerInstance *getCompilerInstance();
0147 llvm::Expected<llvm::orc::LLJIT &> getExecutionEngine();
0148
0149 llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Code);
0150 llvm::Error Execute(PartialTranslationUnit &T);
0151 llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V = nullptr);
0152
0153
0154 llvm::Error Undo(unsigned N = 1);
0155
0156
0157 llvm::Error LoadDynamicLibrary(const char *name);
0158
0159
0160
0161
0162 llvm::Expected<llvm::orc::ExecutorAddr> getSymbolAddress(GlobalDecl GD) const;
0163
0164
0165 llvm::Expected<llvm::orc::ExecutorAddr>
0166 getSymbolAddress(llvm::StringRef IRName) const;
0167
0168
0169
0170 llvm::Expected<llvm::orc::ExecutorAddr>
0171 getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;
0172
0173 const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() const {
0174 return ValuePrintingInfo;
0175 }
0176
0177 Expr *SynthesizeExpr(Expr *E);
0178
0179 private:
0180 size_t getEffectivePTUSize() const;
0181 void markUserCodeStart();
0182 llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E);
0183 llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD);
0184
0185 CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const;
0186 std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr);
0187 PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
0188 std::unique_ptr<llvm::Module> M = {},
0189 IncrementalAction *Action = nullptr);
0190
0191
0192
0193 llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
0194
0195 llvm::SmallVector<Expr *, 4> ValuePrintingInfo;
0196
0197 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder;
0198 };
0199 }
0200
0201 #endif