[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 501360. junaire added a comment. Support printing temporaries. Note there's a ugly hack because I didn't find the right way to synthesize the AST for explicit destructor call. 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/Interpreter/Value.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/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,32 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + std::vector MagicFunctions = { + "void __InterpreterSetValueNoAlloc(void*, void*, void*, bool);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, char);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, signed char);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, short);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, int);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, long);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, long long);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, unsigned char);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, unsigned short);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, unsigned int);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, unsigned long);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, unsigned long " + "long);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, float);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, double);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*, void*);", + "void* __InterpreterSetValueWithAlloc(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } + llvm::cantFail(Interp.ParseAndExecute("#include ")); +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +139,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,23 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +char c = 'a'; +c +// CHECK: (char) a + +int x = 42; +x +// CHECK-NEXT: (int) 42 + +float f = 4.2f; +f +// CHECK-NEXT: (float) 4.2 + +double d = 4.21; +d +// CHECK-NEXT: (double) 4.21 + +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ return true; } -bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed) { +bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed, + bool IsTopExpr) { if
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 499804. junaire added a comment. Rename the interface. 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/Interpreter/Value.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/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,29 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + std::vector MagicFunctions = { + "void __InterpreterSetValueNoAlloc(void*, void*, bool);", + "void __InterpreterSetValueNoAlloc(void*, void*, char);", + "void __InterpreterSetValueNoAlloc(void*, void*, signed char);", + "void __InterpreterSetValueNoAlloc(void*, void*, short);", + "void __InterpreterSetValueNoAlloc(void*, void*, int);", + "void __InterpreterSetValueNoAlloc(void*, void*, long);", + "void __InterpreterSetValueNoAlloc(void*, void*, long long);", + "void __InterpreterSetValueNoAlloc(void*, void*, unsigned char);", + "void __InterpreterSetValueNoAlloc(void*, void*, unsigned short);", + "void __InterpreterSetValueNoAlloc(void*, void*, unsigned int);", + "void __InterpreterSetValueNoAlloc(void*, void*, unsigned long);", + "void __InterpreterSetValueNoAlloc(void*, void*, unsigned long long);", + "void __InterpreterSetValueNoAlloc(void*, void*, float);", + "void __InterpreterSetValueNoAlloc(void*, void*, double);", + "void __InterpreterSetValueNoAlloc(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +136,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,23 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +char c = 'a'; +c +// CHECK: (char) a + +int x = 42; +x +// CHECK-NEXT: (int) 42 + +float f = 4.2f; +f +// CHECK-NEXT: (float) 4.2 + +double d = 4.21; +d +// CHECK-NEXT: (double) 4.21 + +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ 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(); +
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 499801. junaire added a comment. Update tests. 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/Interpreter/Value.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/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,29 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + std::vector MagicFunctions = { + "void __InterpreterCreateValue(void*, void*, bool);", + "void __InterpreterCreateValue(void*, void*, char);", + "void __InterpreterCreateValue(void*, void*, signed char);", + "void __InterpreterCreateValue(void*, void*, short);", + "void __InterpreterCreateValue(void*, void*, int);", + "void __InterpreterCreateValue(void*, void*, long);", + "void __InterpreterCreateValue(void*, void*, long long);", + "void __InterpreterCreateValue(void*, void*, unsigned char);", + "void __InterpreterCreateValue(void*, void*, unsigned short);", + "void __InterpreterCreateValue(void*, void*, unsigned int);", + "void __InterpreterCreateValue(void*, void*, unsigned long);", + "void __InterpreterCreateValue(void*, void*, unsigned long long);", + "void __InterpreterCreateValue(void*, void*, float);", + "void __InterpreterCreateValue(void*, void*, double);", + "void __InterpreterCreateValue(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +136,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,23 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +char c = 'a'; +c +// CHECK: (char) a + +int x = 42; +x +// CHECK-NEXT: (int) 42 + +float f = 4.2f; +f +// CHECK-NEXT: (float) 4.2 + +double d = 4.21; +d +// CHECK-NEXT: (double) 4.21 + +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ 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)) {
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 498655. junaire added a comment. Update. 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/Interpreter/Value.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/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,29 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + std::vector MagicFunctions = { + "void __InterpreterCreateValue(void*, void*, bool);", + "void __InterpreterCreateValue(void*, void*, char);", + "void __InterpreterCreateValue(void*, void*, signed char);", + "void __InterpreterCreateValue(void*, void*, short);", + "void __InterpreterCreateValue(void*, void*, int);", + "void __InterpreterCreateValue(void*, void*, long);", + "void __InterpreterCreateValue(void*, void*, long long);", + "void __InterpreterCreateValue(void*, void*, unsigned char);", + "void __InterpreterCreateValue(void*, void*, unsigned short);", + "void __InterpreterCreateValue(void*, void*, unsigned int);", + "void __InterpreterCreateValue(void*, void*, unsigned long);", + "void __InterpreterCreateValue(void*, void*, unsigned long long);", + "void __InterpreterCreateValue(void*, void*, float);", + "void __InterpreterCreateValue(void*, void*, double);", + "void __InterpreterCreateValue(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +136,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,12 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +int x = 42; +x +// CHECK: (int) 42 +x - 2 +// CHECK-NEXT: (int) 40 +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ 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
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 497531. junaire added a comment. Herald added a subscriber: mstorsjo. Update 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/Interpreter/Value.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/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,29 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + llvm::ArrayRef MagicFunctions = { + "void __InterpreterCreateValue(void*, void*, bool);", + "void __InterpreterCreateValue(void*, void*, char);", + "void __InterpreterCreateValue(void*, void*, signed char);", + "void __InterpreterCreateValue(void*, void*, short);", + "void __InterpreterCreateValue(void*, void*, int);", + "void __InterpreterCreateValue(void*, void*, long);", + "void __InterpreterCreateValue(void*, void*, long long);", + "void __InterpreterCreateValue(void*, void*, unsigned char);", + "void __InterpreterCreateValue(void*, void*, unsigned short);", + "void __InterpreterCreateValue(void*, void*, unsigned int);", + "void __InterpreterCreateValue(void*, void*, unsigned long);", + "void __InterpreterCreateValue(void*, void*, unsigned long long);", + "void __InterpreterCreateValue(void*, void*, float);", + "void __InterpreterCreateValue(void*, void*, double);", + "void __InterpreterCreateValue(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +136,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,12 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +int x = 42; +x +// CHECK: (int) 42 +x - 2 +// CHECK-NEXT: (int) 40 +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ 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:
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 497011. junaire added a comment. Update 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/Interpreter/Value.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/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,29 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + llvm::ArrayRef MagicFunctions = { + "void __InterpreterCreateValue(void*, void*, bool);", + "void __InterpreterCreateValue(void*, void*, char);", + "void __InterpreterCreateValue(void*, void*, signed char);", + "void __InterpreterCreateValue(void*, void*, short);", + "void __InterpreterCreateValue(void*, void*, int);", + "void __InterpreterCreateValue(void*, void*, long);", + "void __InterpreterCreateValue(void*, void*, long long);", + "void __InterpreterCreateValue(void*, void*, unsigned char);", + "void __InterpreterCreateValue(void*, void*, unsigned short);", + "void __InterpreterCreateValue(void*, void*, unsigned int);", + "void __InterpreterCreateValue(void*, void*, unsigned long);", + "void __InterpreterCreateValue(void*, void*, unsigned long long);", + "void __InterpreterCreateValue(void*, void*, float);", + "void __InterpreterCreateValue(void*, void*, double);", + "void __InterpreterCreateValue(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +136,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,12 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +int x = 42; +x +// CHECK: (int) 42 +x - 2 +// CHECK-NEXT: (int) 40 +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ 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
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 494865. junaire added a comment. Update 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/Interpreter/Value.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/Value.cpp clang/lib/Interpreter/ValueSynthesize.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,29 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + llvm::ArrayRef MagicFunctions = { + "void __InterpreterCreateValue(void*, void*, bool);", + "void __InterpreterCreateValue(void*, void*, char);", + "void __InterpreterCreateValue(void*, void*, signed char);", + "void __InterpreterCreateValue(void*, void*, short);", + "void __InterpreterCreateValue(void*, void*, int);", + "void __InterpreterCreateValue(void*, void*, long);", + "void __InterpreterCreateValue(void*, void*, long long);", + "void __InterpreterCreateValue(void*, void*, unsigned char);", + "void __InterpreterCreateValue(void*, void*, unsigned short);", + "void __InterpreterCreateValue(void*, void*, unsigned int);", + "void __InterpreterCreateValue(void*, void*, unsigned long);", + "void __InterpreterCreateValue(void*, void*, unsigned long long);", + "void __InterpreterCreateValue(void*, void*, float);", + "void __InterpreterCreateValue(void*, void*, double);", + "void __InterpreterCreateValue(void*, void*, void*);"}; + + for (llvm::StringRef Function : MagicFunctions) { +llvm::cantFail(Interp.ParseAndExecute(Function)); + } +} + llvm::ExitOnError ExitOnErr; int main(int argc, const char **argv) { ExitOnErr.setBanner("clang-repl: "); @@ -110,6 +136,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,12 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +int x = 42; +x +// CHECK: (int) 42 +x - 2 +// CHECK-NEXT: (int) 40 +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -154,10 +154,20 @@ 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:
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 492665. junaire added a comment. Herald added a subscriber: ChuanqiXu. Update 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/Interpreter/Value.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/Value.cpp clang/lib/Interpreter/ValueSynthesize.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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* @@ -66,6 +69,18 @@ return (Errs || HasError) ? EXIT_FAILURE : EXIT_SUCCESS; } +static void DeclareMagicFunctions(clang::Interpreter ) { + llvm::ArrayRef MagicFunctions = { + "void __InterpreterCreateValue(void*, void*, char);", + "void __InterpreterCreateValue(void*, void*, int);", + "void __InterpreterCreateValue(void*, void*, float);", + "void __InterpreterCreateValue(void*, 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: "); @@ -110,6 +125,7 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,12 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +int x = 42; +x +// CHECK: (int) 42 +x - 2 +// CHECK-NEXT: (int) 40 +%quit + Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -153,10 +153,20 @@ 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 @@ -542,9 +542,9 @@ // 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/ValueSynthesize.cpp
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 488502. junaire added a comment. Introduce `Value` class 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/Interpreter/Value.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/Interpreter/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Interpreter/pretty-print.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 ) { + llvm::ArrayRef 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 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/test/Interpreter/pretty-print.cpp === --- /dev/null +++ clang/test/Interpreter/pretty-print.cpp @@ -0,0 +1,11 @@ +// RUN: clang-repl "int i = 10;" 'extern "C" int printf(const char*,...);' \ +// RUN:'auto r1 = printf("i = %d\n", i);' | FileCheck --check-prefix=CHECK-DRIVER %s +// UNSUPPORTED: system-aix +// CHECK-DRIVER: i = 10 +// RUN: cat %s | clang-repl | FileCheck %s +int x = 42; +x +// CHECK: [int]: 42 +x + 42 +// CHECK-NEXT: [int]: 84 +%quit Index: clang/lib/Parse/Parser.cpp === --- clang/lib/Parse/Parser.cpp +++ clang/lib/Parse/Parser.cpp @@ -153,10 +153,20 @@ 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
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
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 ) { + llvm::ArrayRef 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 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
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire updated this revision to Diff 488158. junaire added a comment. Make build bots happy 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/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/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 ) { + llvm::ArrayRef 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,21 +124,57 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter while (llvm::Optional 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; } continue; } + // TODO: Find a more reliable way to determine if this is something we + // need to prettty print. + if (!Code.starts_with("//") && !Code.starts_with("#") && + !Code.ends_with("}") && !Code.ends_with(";")) { +clang::Interpreter::PrettyPrintRAII X(*Interp); +// Capture the expression we want to print. +auto ExprOrErr = Interp->CaptureExpr(Code); +if (!ExprOrErr) { + llvm::logAllUnhandledErrors(ExprOrErr.takeError(), llvm::errs(), + "error: "); + HasError = true; +} else { + // Synthesize a CallExpr to `__InterpreterPrettyPrint`. + clang::Expr *E = Interp->SynthesizeCall(ExprOrErr.get()); + // Generate a PartialTranslationUnit from the CallExpr. + llvm::Expected SynthesizedPTUOrErr = + Interp->GenPTU(E); + if (!SynthesizedPTUOrErr) { +llvm::logAllUnhandledErrors(SynthesizedPTUOrErr.takeError(), +llvm::errs(), "error: "); +HasError = true; + } + // Let JIT handle all the rest. + if (auto Err = Interp->Execute(SynthesizedPTUOrErr.get())) { +llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), +"error: "); +HasError = true; + } +} +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/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
[PATCH] D141215: [clang-repl][WIP] Implement pretty printing
junaire created this revision. Herald added a project: All. junaire requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. This patch implements the initial value pretty printing for clang-repl. In general, when clang-repl finds something need to print, it will synthesizes a call to `__InterpreterPrettyPrint` and then calls JIT. Signed-off-by: Jun Zhang Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D141215 Files: clang/include/clang/Interpreter/Interpreter.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/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 ) { + llvm::ArrayRef 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,21 +124,51 @@ bool HasError = false; + DeclareMagicFunctions(*Interp); if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); // FIXME: Add LE.setListCompleter while (llvm::Optional Line = LE.readLine()) { - if (*Line == R"(%quit)") + llvm::StringRef Code = *Line; + 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; } continue; } + if (!Code.starts_with("#") && !Code.ends_with(";")) { +clang::Interpreter::PrettyPrintRAII X(*Interp); +// Capture the expression we want to print. +auto ExprOrErr = Interp->CaptureExpr(Code); +if (!ExprOrErr) { + llvm::logAllUnhandledErrors(ExprOrErr.takeError(), llvm::errs(), + "error: "); + HasError = true; +} else { + // Synthesize a CallExpr to `__InterpreterPrettyPrint`. + clang::Expr *E = Interp->SynthesizeCall(ExprOrErr.get()); + // Generate a PartialTranslationUnit from the CallExpr. + llvm::Expected SynthesizedPTUOrErr = + Interp->GenPTU(E); + if (!SynthesizedPTUOrErr) { +llvm::logAllUnhandledErrors(SynthesizedPTUOrErr.takeError(), +llvm::errs(), "error: "); +HasError = true; + } + // Let JIT handle all the rest. + if (auto Err = Interp->Execute(SynthesizedPTUOrErr.get())) { +llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), +"error: "); +HasError = true; + } +} +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/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