[PATCH] D141215: [clang-repl] Introduce Value to capture expression results

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 12 10:24:26 PDT 2023


aaron.ballman added a comment.

I've not done a complete review yet, but I got started on it and have a handful of comments.



================
Comment at: clang/include/clang/Basic/TokenKinds.def:945
+// Annotation for end of input in clang-repl.
+ANNOTATION(input_end)
+
----------------
Should we name this `repl_input_end` to make it clear this is generally expected to only be used for REPL input?


================
Comment at: clang/include/clang/Interpreter/Interpreter.h:59
+
+  Value LastValue;
 
----------------
I think I'm surprised to see this as a data member of `Interpreter` but mostly because my brain keeps thinking this interpreter is to interpret whole programs, so the idea of a "last value" is a bit odd from that context. The name is probably fine as-is, but I figured it may be worth mentioning just the same.


================
Comment at: clang/include/clang/Interpreter/Interpreter.h:65
   create(std::unique_ptr<CompilerInstance> CI);
+  ASTContext &getASTContext() const;
   const CompilerInstance *getCompilerInstance() const;
----------------
Overload set for some better const correctness.


================
Comment at: clang/include/clang/Interpreter/Interpreter.h:72
+  llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V = nullptr);
+  llvm::Expected<llvm::JITTargetAddress> CompileDtorCall(CXXRecordDecl *CXXRD);
 
----------------
Hopefully this function isn't intending to mutate the passed object?


================
Comment at: clang/include/clang/Interpreter/Interpreter.h:98-100
+  llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() {
+    return ValuePrintingInfo;
+  }
----------------
`const` overload here as well.


================
Comment at: clang/include/clang/Interpreter/Interpreter.h:102
+
+  Expr *SynthesizeExpr(clang::Expr *E);
+
----------------
Any chance we can make this const correct as well? (I'll stop asking in this review -- can you take a pass through it to add const correctness where it isn't obnoxiously viral to do so?)


================
Comment at: clang/include/clang/Interpreter/Value.h:17
+
+#include <cstdint>
+
----------------
Unused include can be removed.


================
Comment at: clang/include/clang/Interpreter/Value.h:43
+
+class Interpreter;
+class QualType;
----------------
Duplicates line 27, can be removed.


================
Comment at: clang/include/clang/Interpreter/Value.h:44
+class Interpreter;
+class QualType;
+
----------------
Move this up to the rest of the forward declarations (and probably keep them in alphabetical order).


================
Comment at: clang/include/clang/Interpreter/Value.h:46
+
+#define REPL_BUILTIN_TYPES                                                     \
+  X(bool, Bool)                                                                \
----------------
Is this expected to be a complete list of builtin types? e.g., should this have `char8_t` and `void` and `wchar_t`, etc? Should this be including `clang/include/clang/AST/BuiltinTypes.def` instead of manually maintaining the list?


================
Comment at: clang/include/clang/Interpreter/Value.h:77
+
+        K_Void,
+    K_PtrOrObj,
----------------
Fixing indentation


================
Comment at: clang/include/clang/Interpreter/Value.h:83
+  Value() = default;
+  Value(void /*Interpreter*/ *In, void /*QualType*/ *Ty);
+  Value(const Value &RHS);
----------------
Why do these take `void *` instead of the expected type?


================
Comment at: clang/include/clang/Interpreter/Value.h:121
+    static T cast(const Value &V) {
+      if (V.isPointerOrObjectType())
+        return (T)(uintptr_t)V.getAs<void *>();
----------------
Do we have to worry about member function pointers where a single pointer value may not be sufficient?


================
Comment at: clang/include/clang/Interpreter/Value.h:143
+  /// Values referencing an object are treated as pointers to the object.
+  template <typename T> T castAs() const { return CastFwd<T>::cast(*this); }
+
----------------
This doesn't match the usual pattern used in Clang where the `get` variant returns `nullptr` and the `cast` variant asserts if the cast would be invalid. Should we go with a similar approach?


================
Comment at: clang/include/clang/Interpreter/Value.h:160-162
+  // Interpreter, QualType are stored as void* to reduce dependencies.
+  void *Interp = nullptr;
+  void *OpaqueType = nullptr;
----------------
Why don't forward declares suffice if we're storing the information by pointer?


================
Comment at: clang/lib/CodeGen/CodeGenModule.cpp:7226
+  // assert(DeferredDeclsToEmit.empty() &&
+  //        "Should have emitted all decls deferred to emit.");
   assert(NewBuilder->DeferredDecls.empty() &&
----------------
v.g.vassilev wrote:
> That should probably be a separate review with a testcase.
+1 -- the codegen code owners should weigh in on whether this is reasonable as a temporary measure or not.


================
Comment at: clang/lib/Interpreter/CMakeLists.txt:14-16
   Interpreter.cpp
+  Value.cpp
+  InterpreterUtils.cpp
----------------
Probably should be kept alphabetical.


================
Comment at: clang/lib/Interpreter/IncrementalParser.h:34
 class Parser;
-
+class Interpreter;
 /// Provides support for incremental compilation. Keeps track of the state
----------------
Alphabetical order


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141215/new/

https://reviews.llvm.org/D141215



More information about the cfe-commits mailing list