junaire updated this revision to Diff 488466.
junaire added a comment.
Let's try a better approach to determine whether we should pretty print the
expression.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D141215/new/
https://reviews.llvm.org/D141215
Files:
clang/include/clang/Interpreter/Interpreter.h
clang/include/clang/Parse/Parser.h
clang/lib/Interpreter/CMakeLists.txt
clang/lib/Interpreter/IncrementalParser.cpp
clang/lib/Interpreter/IncrementalParser.h
clang/lib/Interpreter/Interpreter.cpp
clang/lib/Interpreter/PrettyPrint.cpp
clang/lib/Parse/ParseStmt.cpp
clang/lib/Parse/Parser.cpp
clang/tools/clang-repl/CMakeLists.txt
clang/tools/clang-repl/ClangRepl.cpp
Index: clang/tools/clang-repl/ClangRepl.cpp
===================================================================
--- clang/tools/clang-repl/ClangRepl.cpp
+++ clang/tools/clang-repl/ClangRepl.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -18,6 +19,8 @@
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/LineEditor/LineEditor.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h" // llvm_shutdown
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h" // llvm::Initialize*
@@ -65,6 +68,18 @@
return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS;
}
+static void DeclareMagicFunctions(clang::Interpreter &Interp) {
+ llvm::ArrayRef<llvm::StringRef> MagicFunctions = {
+ "void __InterpreterPrettyPrint(void*, char);",
+ "void __InterpreterPrettyPrint(void*, int);",
+ "void __InterpreterPrettyPrint(void*, float);",
+ "void __InterpreterPrettyPrint(void*, double);",
+ };
+ for (llvm::StringRef Function : MagicFunctions) {
+ llvm::cantFail(Interp.ParseAndExecute(Function));
+ }
+}
+
llvm::ExitOnError ExitOnErr;
int main(int argc, const char **argv) {
ExitOnErr.setBanner("clang-repl: ");
@@ -109,13 +124,18 @@
bool HasError = false;
+ DeclareMagicFunctions(*Interp);
if (OptInputs.empty()) {
llvm::LineEditor LE("clang-repl");
// FIXME: Add LE.setListCompleter
while (llvm::Optional<std::string> Line = LE.readLine()) {
- if (*Line == R"(%quit)")
+ llvm::StringRef Code = *Line;
+ if (Code.empty()) {
+ continue;
+ }
+ if (Code == R"(%quit)")
break;
- if (*Line == R"(%undo)") {
+ if (Code == R"(%undo)") {
if (auto Err = Interp->Undo()) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
HasError = true;
@@ -123,7 +143,7 @@
continue;
}
- if (auto Err = Interp->ParseAndExecute(*Line)) {
+ if (auto Err = Interp->ParseAndExecute(Code)) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
HasError = true;
}
Index: clang/tools/clang-repl/CMakeLists.txt
===================================================================
--- clang/tools/clang-repl/CMakeLists.txt
+++ clang/tools/clang-repl/CMakeLists.txt
@@ -12,6 +12,7 @@
)
clang_target_link_libraries(clang-repl PRIVATE
+ clangAST
clangBasic
clangFrontend
clangInterpreter
Index: clang/lib/Parse/Parser.cpp
===================================================================
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -153,10 +153,19 @@
return true;
}
-bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed) {
+bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed, bool IsTopExpr) {
if (TryConsumeToken(tok::semi))
return false;
+ // If this is in the incremental C++ mode, then it means we need to pretty
+ // print this expression. Thus, let's pretend we have this semi and continue
+ // parsing.
+ if (PP.isIncrementalProcessingEnabled() &&
+ IsTopExpr && DiagID == diag::err_expected_semi_after_expr) {
+ setPrettyPrintMode();
+ return false;
+ }
+
if (Tok.is(tok::code_completion)) {
handleUnexpectedCodeCompletionToken();
return false;
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -541,9 +541,8 @@
// Recover parsing as a case statement.
return ParseCaseStatement(StmtCtx, /*MissingCase=*/true, Expr);
}
-
// Otherwise, eat the semicolon.
- ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
+ ExpectAndConsumeSemi(diag::err_expected_semi_after_expr, /*TokenUsed=*/"", StmtCtx == ParsedStmtContext::SubStmt);
return handleExprStmt(Expr, StmtCtx);
}
Index: clang/lib/Interpreter/PrettyPrint.cpp
===================================================================
--- /dev/null
+++ clang/lib/Interpreter/PrettyPrint.cpp
@@ -0,0 +1,37 @@
+#include "clang/AST/Type.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+static void PrintType(void *OpaqueType) {
+ QualType *QT = reinterpret_cast<QualType *>(OpaqueType);
+ assert(QT && "type can't be null during value pretty printing");
+ llvm::errs() << "[" << QT->getAsString() << "]";
+}
+
+template <typename T> static void PrintImpl(void *OpaqueType, T Val) {
+ PrintType(OpaqueType);
+ llvm::errs() << ": ";
+ llvm::errs() << Val;
+ llvm::errs() << "\n";
+}
+
+LLVM_EXTERNAL_VISIBILITY void __InterpreterPrettyPrint(void *OpaqueType,
+ char Val) {
+ PrintImpl(OpaqueType, Val);
+}
+
+LLVM_EXTERNAL_VISIBILITY void __InterpreterPrettyPrint(void *OpaqueType,
+ int Val) {
+ PrintImpl(OpaqueType, Val);
+}
+
+LLVM_EXTERNAL_VISIBILITY void __InterpreterPrettyPrint(void *OpaqueType,
+ float Val) {
+ PrintImpl(OpaqueType, Val);
+}
+
+LLVM_EXTERNAL_VISIBILITY void __InterpreterPrettyPrint(void *OpaqueType,
+ double Val) {
+ PrintImpl(OpaqueType, Val);
+}
Index: clang/lib/Interpreter/Interpreter.cpp
===================================================================
--- clang/lib/Interpreter/Interpreter.cpp
+++ clang/lib/Interpreter/Interpreter.cpp
@@ -15,8 +15,9 @@
#include "IncrementalExecutor.h"
#include "IncrementalParser.h"
-
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
@@ -27,10 +28,15 @@
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Interpreter/PartialTranslationUnit.h"
#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Host.h"
using namespace clang;
@@ -235,6 +241,34 @@
return llvm::Error::success();
}
+llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code) {
+ auto PTU = Parse(Code);
+ if (!PTU)
+ return PTU.takeError();
+ if (IncrParser->isPrettyPrintMode()) {
+ IncrParser->setPrettyPrintMode(false);
+
+ // Capture the expression we want to print.
+ auto ExprOrErr = CaptureExpr(*PTU->TUPart);
+ if (!ExprOrErr)
+ return ExprOrErr.takeError();
+ // Synthesize a CallExpr to `__InterpreterPrettyPrint`.
+ clang::Expr *E = SynthesizeCall(ExprOrErr.get());
+ // Generate a PartialTranslationUnit from the CallExpr.
+ llvm::Expected<clang::PartialTranslationUnit &> SynthesizedPTUOrErr =
+ GenPTU(E);
+ if (!SynthesizedPTUOrErr)
+ return SynthesizedPTUOrErr.takeError();
+
+ if (SynthesizedPTUOrErr->TheModule)
+ return Execute(*SynthesizedPTUOrErr);
+ return llvm::Error::success();
+ }
+ if (PTU->TheModule)
+ return Execute(*PTU);
+ return llvm::Error::success();
+}
+
llvm::Expected<llvm::JITTargetAddress>
Interpreter::getSymbolAddress(GlobalDecl GD) const {
if (!IncrExecutor)
@@ -283,3 +317,79 @@
}
return llvm::Error::success();
}
+
+llvm::Expected<Expr *> Interpreter::CaptureExpr(TranslationUnitDecl &TU) {
+ for (auto *D : TU.decls()) {
+ if (const auto *S = llvm::dyn_cast<clang::TopLevelStmtDecl>(D)) {
+ if (const auto *E = llvm::dyn_cast<clang::Expr>(S->getStmt())) {
+ return const_cast<Expr *>(E);
+ }
+ }
+ }
+ return llvm::make_error<llvm::StringError>("Can not capture any Expr*!",
+ std::error_code());
+}
+
+llvm::Expected<PartialTranslationUnit &> Interpreter::GenPTU(clang::Expr *E) {
+ Sema &S = getCompilerInstance()->getSema();
+ SmallVector<Decl *, 2> DeclsInGroup;
+ DeclsInGroup.push_back(S.ActOnTopLevelStmtDecl(E));
+ Sema::DeclGroupPtrTy DeclGroupPtr = S.BuildDeclaratorGroup(DeclsInGroup);
+ return IncrParser->Parse(DeclGroupPtr);
+}
+
+static constexpr llvm::StringRef MagicRuntimeInterface =
+ "__InterpreterPrettyPrint";
+
+bool Interpreter::FindRuntimeInterface() {
+ if (RuntimeInterface)
+ return true;
+
+ Sema &S = getCompilerInstance()->getSema();
+ ASTContext &Ctx = S.getASTContext();
+ LookupResult R(S, &Ctx.Idents.get(MagicRuntimeInterface), SourceLocation(),
+ Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration);
+ S.LookupQualifiedName(R, Ctx.getTranslationUnitDecl());
+ if (R.empty()) {
+ return false;
+ }
+ CXXScopeSpec CSS;
+ RuntimeInterface = S.BuildDeclarationNameExpr(CSS, R, /*ADL=*/false).get();
+ return true;
+}
+
+static IntegerLiteral *IntegerLiteralExpr(ASTContext &C, uintptr_t Ptr) {
+ const llvm::APInt Addr(8 * sizeof(void *), Ptr);
+ return IntegerLiteral::Create(C, Addr, C.getUIntPtrType(), SourceLocation());
+}
+
+static Expr *CStyleCastPtrExpr(Sema *S, QualType Ty, Expr *E) {
+ ASTContext &Ctx = S->getASTContext();
+ if (!Ty->isPointerType())
+ Ty = Ctx.getPointerType(Ty);
+
+ TypeSourceInfo *TSI = Ctx.getTrivialTypeSourceInfo(Ty, SourceLocation());
+ Expr *Result =
+ S->BuildCStyleCastExpr(SourceLocation(), TSI, SourceLocation(), E).get();
+ assert(Result && "Cannot create CStyleCastPtrExpr");
+ return Result;
+}
+
+static Expr *CStyleCastPtrExpr(Sema *S, QualType Ty, uintptr_t Ptr) {
+ ASTContext &Ctx = S->getASTContext();
+ return CStyleCastPtrExpr(S, Ty, IntegerLiteralExpr(Ctx, Ptr));
+}
+
+Expr *Interpreter::SynthesizeCall(clang::Expr *E) {
+ Sema &S = getCompilerInstance()->getSema();
+ if (!FindRuntimeInterface()) {
+ llvm_unreachable("We can't find the runtime iterface for pretty print!");
+ }
+ Expr *TypeArg = CStyleCastPtrExpr(&S, S.getASTContext().VoidPtrTy,
+ (uintptr_t)E->getType().getAsOpaquePtr());
+ llvm::SmallVector<Expr *, 2> Args = {TypeArg, E};
+ ExprResult Result = S.ActOnCallExpr(/*Scope=*/nullptr, RuntimeInterface,
+ E->getBeginLoc(), Args, E->getEndLoc());
+ assert(!Result.isInvalid() && "Failed to generate the CallExpr!");
+ return Result.get();
+}
Index: clang/lib/Interpreter/IncrementalParser.h
===================================================================
--- clang/lib/Interpreter/IncrementalParser.h
+++ clang/lib/Interpreter/IncrementalParser.h
@@ -16,7 +16,7 @@
#include "clang/Interpreter/PartialTranslationUnit.h"
#include "clang/AST/GlobalDecl.h"
-
+#include "clang/Parse/Parser.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -32,7 +32,7 @@
class CompilerInstance;
class IncrementalAction;
class Parser;
-
+class Interpreter;
/// Provides support for incremental compilation. Keeps track of the state
/// changes between the subsequent incremental input.
///
@@ -49,9 +49,6 @@
/// Consumer to process the produced top level decls. Owned by Act.
ASTConsumer *Consumer = nullptr;
- /// Counts the number of direct user input lines that have been parsed.
- unsigned InputCount = 0;
-
/// List containing every information about every incrementally parsed piece
/// of code.
std::list<PartialTranslationUnit> PTUs;
@@ -68,6 +65,8 @@
/// \c TranslationUnitDecl and \c llvm::Module corresponding to the input.
llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Input);
+ llvm::Expected<PartialTranslationUnit &> Parse(Parser::DeclGroupPtrTy D);
+
/// Uses the CodeGenModule mangled name cache and avoids recomputing.
///\returns the mangled name of a \c GD.
llvm::StringRef GetMangledName(GlobalDecl GD) const;
@@ -76,8 +75,11 @@
std::list<PartialTranslationUnit> &getPTUs() { return PTUs; }
-private:
- llvm::Expected<PartialTranslationUnit &> ParseOrWrapTopLevelDecl();
+ llvm::Expected<PartialTranslationUnit &>
+ ParseOrWrapTopLevelDecl(Parser::DeclGroupPtrTy SynthesizedDecl = nullptr);
+
+ bool isPrettyPrintMode() const { return P->isPrettyPrintMode(); }
+ void setPrettyPrintMode(bool Mode = true) { P->setPrettyPrintMode(Mode); }
};
} // end namespace clang
Index: clang/lib/Interpreter/IncrementalParser.cpp
===================================================================
--- clang/lib/Interpreter/IncrementalParser.cpp
+++ clang/lib/Interpreter/IncrementalParser.cpp
@@ -19,9 +19,9 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/FrontendTool/Utils.h"
+#include "clang/Interpreter/Interpreter.h"
#include "clang/Parse/Parser.h"
#include "clang/Sema/Sema.h"
-
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Error.h"
@@ -143,7 +143,8 @@
}
llvm::Expected<PartialTranslationUnit &>
-IncrementalParser::ParseOrWrapTopLevelDecl() {
+IncrementalParser::ParseOrWrapTopLevelDecl(
+ Parser::DeclGroupPtrTy SynthesizedDecl) {
// Recover resources if we crash before exiting this method.
Sema &S = CI->getSema();
llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S);
@@ -169,14 +170,24 @@
S.ActOnTranslationUnitScope(P->getCurScope());
}
- Parser::DeclGroupPtrTy ADecl;
- Sema::ModuleImportState ImportState;
- for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
- AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) {
- if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
- return llvm::make_error<llvm::StringError>("Parsing failed. "
- "The consumer rejected a decl",
- std::error_code());
+ if (SynthesizedDecl) {
+ if (!Consumer->HandleTopLevelDecl(SynthesizedDecl.get())) {
+ return llvm::make_error<llvm::StringError>(
+ "Parsing failed. "
+ "The consumer rejected the synthesized decl",
+ std::error_code());
+ }
+ } else {
+ Parser::DeclGroupPtrTy ADecl;
+ Sema::ModuleImportState ImportState;
+ for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
+ AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) {
+ if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
+ return llvm::make_error<llvm::StringError>(
+ "Parsing failed. "
+ "The consumer rejected a decl",
+ std::error_code());
+ }
}
DiagnosticsEngine &Diags = getCI()->getDiagnostics();
@@ -213,24 +224,31 @@
return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
}
-llvm::Expected<PartialTranslationUnit &>
-IncrementalParser::Parse(llvm::StringRef input) {
- Preprocessor &PP = CI->getPreprocessor();
- assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?");
-
+static std::unique_ptr<llvm::MemoryBuffer> MakeInputBuf(StringRef Input) {
+ /// Counts the number of direct user input lines that have been parsed.
+ static unsigned InputCount = 0;
std::ostringstream SourceName;
SourceName << "input_line_" << InputCount++;
-
// Create an uninitialized memory buffer, copy code in and append "\n"
- size_t InputSize = input.size(); // don't include trailing 0
+ size_t InputSize = Input.size(); // don't include trailing 0
+ size_t AllocSize = Input.size() + 1;
+
// MemBuffer size should *not* include terminating zero
std::unique_ptr<llvm::MemoryBuffer> MB(
- llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
+ llvm::WritableMemoryBuffer::getNewUninitMemBuffer(AllocSize,
SourceName.str()));
char *MBStart = const_cast<char *>(MB->getBufferStart());
- memcpy(MBStart, input.data(), InputSize);
- MBStart[InputSize] = '\n';
+ memcpy(MBStart, Input.data(), InputSize);
+ MBStart[AllocSize - 1] = '\n';
+ return MB;
+}
+llvm::Expected<PartialTranslationUnit &>
+IncrementalParser::Parse(llvm::StringRef input) {
+ Preprocessor &PP = CI->getPreprocessor();
+ assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?");
+
+ std::unique_ptr<llvm::MemoryBuffer> MB = MakeInputBuf(input);
SourceManager &SM = CI->getSourceManager();
// FIXME: Create SourceLocation, which will allow clang to order the overload
@@ -278,6 +296,24 @@
return PTU;
}
+llvm::Expected<PartialTranslationUnit &>
+IncrementalParser::Parse(Parser::DeclGroupPtrTy D) {
+ llvm::Expected<PartialTranslationUnit &> PTUOrErr =
+ ParseOrWrapTopLevelDecl(D);
+ if (!PTUOrErr) {
+ return PTUOrErr.takeError();
+ }
+ if (CodeGenerator *CG = getCodeGen(Act.get())) {
+ std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
+ CG->StartModule("incr_module_" + std::to_string(PTUs.size()),
+ M->getContext());
+
+ PTUOrErr.get().TheModule = std::move(M);
+ }
+
+ return PTUOrErr;
+}
+
void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
TranslationUnitDecl *MostRecentTU = PTU.TUPart;
TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl();
Index: clang/lib/Interpreter/CMakeLists.txt
===================================================================
--- clang/lib/Interpreter/CMakeLists.txt
+++ clang/lib/Interpreter/CMakeLists.txt
@@ -12,6 +12,7 @@
IncrementalExecutor.cpp
IncrementalParser.cpp
Interpreter.cpp
+ PrettyPrint.cpp
DEPENDS
intrinsics_gen
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -435,6 +435,10 @@
/// a statement expression and builds a suitable expression statement.
StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx);
+ /// A flag that indicate if we run into something that need to pretty print.
+ /// Note this should only be used in incremental C++ (clang-repl).
+ bool PrettyPrintMode = false;
+
public:
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
~Parser() override;
@@ -455,6 +459,17 @@
return Actions.getObjCDeclContext();
}
+ bool isPrettyPrintMode() const {
+ assert(PP.isIncrementalProcessingEnabled() &&
+ "This should only be used in incremental C++");
+ return PrettyPrintMode;
+ }
+ void setPrettyPrintMode(bool Mode = true) {
+ assert(PP.isIncrementalProcessingEnabled() &&
+ "This should only be used in incremental C++");
+ PrettyPrintMode = Mode;
+ }
+
// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
@@ -1058,7 +1073,7 @@
/// If the next token is not a semicolon, this emits the specified diagnostic,
/// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
/// to the semicolon, consumes that extra token.
- bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = "");
+ bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = "", bool IsTopExpr = false);
/// The kind of extra semi diagnostic to emit.
enum ExtraSemiKind {
Index: clang/include/clang/Interpreter/Interpreter.h
===================================================================
--- clang/include/clang/Interpreter/Interpreter.h
+++ clang/include/clang/Interpreter/Interpreter.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
#define LLVM_CLANG_INTERPRETER_INTERPRETER_H
+#include "clang/AST/Decl.h"
#include "clang/Interpreter/PartialTranslationUnit.h"
#include "clang/AST/GlobalDecl.h"
@@ -49,6 +50,7 @@
std::unique_ptr<llvm::orc::ThreadSafeContext> TSCtx;
std::unique_ptr<IncrementalParser> IncrParser;
std::unique_ptr<IncrementalExecutor> IncrExecutor;
+ Expr *RuntimeInterface = nullptr;
Interpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &Err);
@@ -60,14 +62,7 @@
const llvm::orc::LLJIT *getExecutionEngine() const;
llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Code);
llvm::Error Execute(PartialTranslationUnit &T);
- llvm::Error ParseAndExecute(llvm::StringRef Code) {
- auto PTU = Parse(Code);
- if (!PTU)
- return PTU.takeError();
- if (PTU->TheModule)
- return Execute(*PTU);
- return llvm::Error::success();
- }
+ llvm::Error ParseAndExecute(llvm::StringRef Code);
/// Undo N previous incremental inputs.
llvm::Error Undo(unsigned N = 1);
@@ -85,6 +80,14 @@
/// file.
llvm::Expected<llvm::JITTargetAddress>
getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;
+
+ llvm::Expected<Expr *> CaptureExpr(TranslationUnitDecl &TU);
+
+ bool FindRuntimeInterface();
+
+ Expr *SynthesizeCall(clang::Expr *E);
+
+ llvm::Expected<PartialTranslationUnit &> GenPTU(clang::Expr *E);
};
} // namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits