[PATCH] D141215: [clang-repl][WIP] Implement pretty printing

2023-02-28 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-02-23 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-02-23 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-02-18 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-02-14 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-02-13 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-02-04 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-01-27 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-01-12 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-01-11 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-01-11 Thread Jun Zhang via Phabricator via cfe-commits
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

2023-01-07 Thread Jun Zhang via Phabricator via cfe-commits
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