-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang-repl] Implement value printing of custom types #84769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
You can test this locally with the following command:git-clang-format --diff b4feb26606de84ff53d9b65a3b79c00a2b4d7c22 9554375738fcfaebab36e41f57618dafc5d7264c --extensions c,h,cpp -- clang/lib/Headers/__clang_interpreter_runtime_printvalue.h clang/lib/Interpreter/InterpreterValuePrinter.cpp clang/test/Interpreter/pretty-print.cpp clang/include/clang/AST/ASTContext.h clang/include/clang/Frontend/MultiplexConsumer.h clang/include/clang/Interpreter/Interpreter.h clang/include/clang/Interpreter/Value.h clang/lib/Frontend/MultiplexConsumer.cpp clang/lib/Interpreter/DeviceOffload.cpp clang/lib/Interpreter/DeviceOffload.h clang/lib/Interpreter/IncrementalExecutor.h clang/lib/Interpreter/IncrementalParser.cpp clang/lib/Interpreter/IncrementalParser.h clang/lib/Interpreter/Interpreter.cpp clang/lib/Interpreter/InterpreterUtils.cpp clang/lib/Interpreter/InterpreterUtils.h clang/lib/Interpreter/Value.cpp clang/lib/Parse/ParseStmt.cpp clang/test/Interpreter/pretty-print.c clang/tools/clang-repl/ClangRepl.cpp clang/unittests/Interpreter/CodeCompletionTest.cpp clang/unittests/Interpreter/InterpreterExtensionsTest.cpp View the diff from clang-format here.diff --git a/clang/include/clang/Interpreter/Value.h b/clang/include/clang/Interpreter/Value.h
index 664f9e9008..c63d4236cc 100644
--- a/clang/include/clang/Interpreter/Value.h
+++ b/clang/include/clang/Interpreter/Value.h
@@ -178,7 +178,7 @@ protected:
template <typename T> struct convertFwd {
static T cast(const Value &V) {
if (V.isPointerOrObjectType())
- return *(T*)(uintptr_t)V.as<void *>();
+ return *(T *)(uintptr_t)V.as<void *>();
if (!V.isValid() || V.isVoid()) {
return T();
}
diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
index df2ee3edcc..374b36db68 100644
--- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp
+++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
@@ -280,13 +280,13 @@ static clang::LookupResult LookupUserDefined(Sema &S, QualType QT) {
ASTContext &Ctx = S.getASTContext();
if (S.getLangOpts().CPlusPlus) {
if (auto *NSD = dyn_cast_or_null<NamespaceDecl>(LookupNamed(S, "caas")))
- if (NamedDecl* RtD = LookupNamed(S, "runtime", NSD)) {
+ if (NamedDecl *RtD = LookupNamed(S, "runtime", NSD)) {
Name = S.PP.getIdentifierInfo("to_string");
LookupResult R(S, Name, SourceLocation(), Sema::LookupOrdinaryName);
S.LookupQualifiedName(R, cast<DeclContext>(RtD)->getPrimaryContext());
LookupResult::Filter F = R.makeFilter();
while (F.hasNext()) {
- NamedDecl* D = F.next();
+ NamedDecl *D = F.next();
FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
if (!FD && isa<FunctionTemplateDecl>(D))
FD = cast<FunctionTemplateDecl>(D)->getTemplatedDecl();
@@ -325,10 +325,12 @@ static clang::LookupResult LookupUserDefined(Sema &S, QualType QT) {
namespace clang {
-std::string Interpreter::CallUserSpecifiedPrinter(LookupResult &R, const Value &V) {
+std::string Interpreter::CallUserSpecifiedPrinter(LookupResult &R,
+ const Value &V) {
assert(!R.empty());
// if (!R.isSingleResult())
- // return "{error: multiple results for '" + R.getLookupName().getAsString() +
+ // return "{error: multiple results for '" + R.getLookupName().getAsString()
+ // +
// "'}";
Sema &S = getCompilerInstance()->getSema();
@@ -338,7 +340,8 @@ std::string Interpreter::CallUserSpecifiedPrinter(LookupResult &R, const Value &
QualType RetTy = Ctx.getPointerType(Ctx.CharTy.withConst());
if (Ctx.getLangOpts().CPlusPlus) {
if (!S.StdNamespace)
- return "{error: user-defined pretty printers require std::string; consider #include <string> }";
+ return "{error: user-defined pretty printers require std::string; "
+ "consider #include <string> }";
// Find and cache std::string.
if (S.StdNamespace && !StdString)
StdString = LookupNamed(S, "string", S.getStdNamespace());
@@ -378,13 +381,13 @@ std::string Interpreter::CallUserSpecifiedPrinter(LookupResult &R, const Value &
if (auto *Main = AddrOrErr->toPtr<std::string (*)()>())
return (*Main)();
} else {
- if (auto *Main = AddrOrErr->toPtr<const char* (*)()>())
+ if (auto *Main = AddrOrErr->toPtr<const char *(*)()>())
return (*Main)();
}
return "{Unable to print the value!}";
}
-struct ValueRef: public Value {
+struct ValueRef : public Value {
ValueRef(Interpreter *In, void *Ty) : Value(In, Ty) {
// Tell the base class to not try to deallocate if it manages the value.
IsManuallyAlloc = false;
@@ -403,21 +406,22 @@ std::string Interpreter::ValueDataToString(const Value &V) {
for (unsigned Idx = 0, N = CAT->getZExtSize(); Idx < N; ++Idx) {
QualType ElemTy = CAT->getElementType();
ValueRef InnerV = ValueRef(this, ElemTy.getAsOpaquePtr());
- const Type* BaseTy = CAT->getBaseElementTypeUnsafe();
+ const Type *BaseTy = CAT->getBaseElementTypeUnsafe();
if (ElemTy->isBuiltinType()) {
// Arrays model builtin types as a pointer to the builtin. We should
// build the dereference to the element type if it is stored as a
// builtin.
InnerV.setData(V.convertTo<long double>());
} else {
- uintptr_t offset = (uintptr_t)V.getPtr() + Idx * Ctx.getTypeSize(BaseTy) / 8;
- InnerV.setPtr((void*)offset);
+ uintptr_t offset =
+ (uintptr_t)V.getPtr() + Idx * Ctx.getTypeSize(BaseTy) / 8;
+ InnerV.setPtr((void *)offset);
}
result += ValueDataToString(InnerV);
if (Idx < N - 1)
result += ", ";
}
- result+=" }";
+ result += " }";
return result;
}
|
Hi @weliveindetail, I wanted to put in this PR which I am working from time to time on and will likely be very relevant for out-of-process execution. I still need to rebase it properly to the new "stuff" that landed recently. If you know how to rebase it faster, I would not mind some help... Ideally, I'd like to implement a facility that aids interpreter-synthesized code. Right now the big ugliness is that we expose some API to the interpreter just to be able to send some code over codegen... Another challenge is that we probably want to keep the stl type printing header slim and include only what we need from it. Perhaps looking if an include protector was defined only then include the related value printing primitives... |
cc: @hahnjo, @devajithvs |
The work started as part of https://reviews.llvm.org/D146809 This patch reworks a lot of the infrastructure to enable printing of types for out-of-process execution on embedded devices.
This patch improves the design of the IncrementalParser and Interpreter classes. Now the incremental parser is only responsible for building the partial translation unit declaration and the AST, while the Interpreter fills in the lower level llvm::Module and other JIT-related infrastructure. Finally the Interpreter class now orchestrates the AST and the LLVM IR with the IncrementalParser and IncrementalExecutor classes. The design improvement allows us to rework some of the logic that extracts an interpreter value into the clang::Value object. The new implementation simplifies use-cases which are used for out-of-process execution by allowing interpreter to be inherited or customized with an clang::ASTConsumer. This change will enable completing the pretty printing work which is in llvm#84769
…ss. (#107737) This patch improves the design of the IncrementalParser and Interpreter classes. Now the incremental parser is only responsible for building the partial translation unit declaration and the AST, while the Interpreter fills in the lower level llvm::Module and other JIT-related infrastructure. Finally the Interpreter class now orchestrates the AST and the LLVM IR with the IncrementalParser and IncrementalExecutor classes. The design improvement allows us to rework some of the logic that extracts an interpreter value into the clang::Value object. The new implementation simplifies use-cases which are used for out-of-process execution by allowing interpreter to be inherited or customized with an clang::ASTConsumer. This change will enable completing the pretty printing work which is in #84769
Hey @vgvassilev Just curious to know as to what work is left here and if any help is needed for the same ? I guess pretty printing for even the standard types might be good to have for starters. |
Hey, @vgvassilev Curious to know the status of this. Thank you. |
Differential revision: https://reviews.llvm.org/D146809