[clang] [PATCH] [clang-repl] Builtin Type printing in ValuePrinter.cpp (PR #88729)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 15 06:14:18 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: wlonestar (wlonestar)

<details>
<summary>Changes</summary>



---

Patch is 27.57 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88729.diff


9 Files Affected:

- (modified) clang/include/clang/Interpreter/Interpreter.h (+2) 
- (modified) clang/include/clang/Interpreter/Value.h (+7-1) 
- (modified) clang/lib/Interpreter/CMakeLists.txt (+1) 
- (modified) clang/lib/Interpreter/IncrementalParser.h (+1) 
- (modified) clang/lib/Interpreter/Interpreter.cpp (+6-2) 
- (modified) clang/lib/Interpreter/InterpreterUtils.cpp (+1-1) 
- (modified) clang/lib/Interpreter/InterpreterUtils.h (+1-1) 
- (modified) clang/lib/Interpreter/Value.cpp (+9-4) 
- (added) clang/lib/Interpreter/ValuePrinter.cpp (+751) 


``````````diff
diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h
index 970e0245417b51..3be29bd75cfca7 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -149,6 +149,8 @@ class Interpreter {
   CompilerInstance *getCompilerInstance();
   llvm::Expected<llvm::orc::LLJIT &> getExecutionEngine();
 
+  Sema &getSema() const;
+
   llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Code);
   llvm::Error Execute(PartialTranslationUnit &T);
   llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V = nullptr);
diff --git a/clang/include/clang/Interpreter/Value.h b/clang/include/clang/Interpreter/Value.h
index d70e8f8719026b..186299a84db444 100644
--- a/clang/include/clang/Interpreter/Value.h
+++ b/clang/include/clang/Interpreter/Value.h
@@ -35,6 +35,7 @@
 
 #include "llvm/Support/Compiler.h"
 #include <cstdint>
+#include <string>
 
 // NOTE: Since the REPL itself could also include this runtime, extreme caution
 // should be taken when MAKING CHANGES to this file, especially when INCLUDE NEW
@@ -117,6 +118,8 @@ class REPL_EXTERNAL_VISIBILITY Value {
   Value &operator=(Value &&RHS) noexcept;
   ~Value();
 
+  std::string printValueInternal() const;
+
   void printType(llvm::raw_ostream &Out) const;
   void printData(llvm::raw_ostream &Out) const;
   void print(llvm::raw_ostream &Out) const;
@@ -126,7 +129,7 @@ class REPL_EXTERNAL_VISIBILITY Value {
   ASTContext &getASTContext();
   const ASTContext &getASTContext() const;
   Interpreter &getInterpreter();
-  const Interpreter &getInterpreter() const;
+  Interpreter &getInterpreter() const;
   QualType getType() const;
 
   bool isValid() const { return ValueKind != K_Unspecified; }
@@ -136,6 +139,8 @@ class REPL_EXTERNAL_VISIBILITY Value {
   Kind getKind() const { return ValueKind; }
   void setKind(Kind K) { ValueKind = K; }
   void setOpaqueType(void *Ty) { OpaqueType = Ty; }
+  void setName(std::string name) { Name = name; }
+  std::string getName() const { return Name; }
 
   void *getPtr() const;
   void setPtr(void *Ptr) { Data.m_Ptr = Ptr; }
@@ -197,6 +202,7 @@ class REPL_EXTERNAL_VISIBILITY Value {
   Storage Data;
   Kind ValueKind = K_Unspecified;
   bool IsManuallyAlloc = false;
+  std::string Name;
 };
 
 template <> inline void *Value::as() const {
diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt
index 9065f998f73c47..ea00bdc80f595d 100644
--- a/clang/lib/Interpreter/CMakeLists.txt
+++ b/clang/lib/Interpreter/CMakeLists.txt
@@ -20,6 +20,7 @@ add_clang_library(clangInterpreter
   Interpreter.cpp
   InterpreterUtils.cpp
   Value.cpp
+  ValuePrinter.cpp
 
   DEPENDS
   intrinsics_gen
diff --git a/clang/lib/Interpreter/IncrementalParser.h b/clang/lib/Interpreter/IncrementalParser.h
index e13b74c7f65948..c9acc59b1ed602 100644
--- a/clang/lib/Interpreter/IncrementalParser.h
+++ b/clang/lib/Interpreter/IncrementalParser.h
@@ -67,6 +67,7 @@ class IncrementalParser {
 
   CompilerInstance *getCI() { return CI.get(); }
   CodeGenerator *getCodeGen() const;
+  Parser &getParser() const { return *P; }
 
   /// Parses incremental input by creating an in-memory file.
   ///\returns a \c PartialTranslationUnit which holds information about the
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index cf31456b6950ac..aa6f6657670bca 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -336,6 +336,8 @@ llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
   return IncrExecutor->GetExecutionEngine();
 }
 
+Sema &Interpreter::getSema() const { return getCompilerInstance()->getSema(); }
+
 ASTContext &Interpreter::getASTContext() {
   return getCompilerInstance()->getASTContext();
 }
@@ -427,7 +429,7 @@ llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
 }
 
 llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
-
+  std::string name = Code.str();
   auto PTU = Parse(Code);
   if (!PTU)
     return PTU.takeError();
@@ -437,10 +439,12 @@ llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
 
   if (LastValue.isValid()) {
     if (!V) {
+      LastValue.setName(name);
       LastValue.dump();
       LastValue.clear();
-    } else
+    } else {
       *V = std::move(LastValue);
+    }
   }
   return llvm::Error::success();
 }
diff --git a/clang/lib/Interpreter/InterpreterUtils.cpp b/clang/lib/Interpreter/InterpreterUtils.cpp
index c19cf6aa3156c9..cba64add8c54a7 100644
--- a/clang/lib/Interpreter/InterpreterUtils.cpp
+++ b/clang/lib/Interpreter/InterpreterUtils.cpp
@@ -102,7 +102,7 @@ NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name,
   return nullptr;
 }
 
-std::string GetFullTypeName(ASTContext &Ctx, QualType QT) {
+std::string GetFullTypeName(const ASTContext &Ctx, QualType QT) {
   PrintingPolicy Policy(Ctx.getPrintingPolicy());
   Policy.SuppressScope = false;
   Policy.AnonymousTagLocations = false;
diff --git a/clang/lib/Interpreter/InterpreterUtils.h b/clang/lib/Interpreter/InterpreterUtils.h
index 8df158c17d4919..5699060754fb4d 100644
--- a/clang/lib/Interpreter/InterpreterUtils.h
+++ b/clang/lib/Interpreter/InterpreterUtils.h
@@ -48,7 +48,7 @@ NamespaceDecl *LookupNamespace(Sema &S, llvm::StringRef Name,
 NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name,
                        const DeclContext *Within);
 
-std::string GetFullTypeName(ASTContext &Ctx, QualType QT);
+std::string GetFullTypeName(const ASTContext &Ctx, QualType QT);
 } // namespace clang
 
 #endif
diff --git a/clang/lib/Interpreter/Value.cpp b/clang/lib/Interpreter/Value.cpp
index eb2ce9c9fd3302..ca11093481be89 100644
--- a/clang/lib/Interpreter/Value.cpp
+++ b/clang/lib/Interpreter/Value.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Interpreter/Value.h"
+#include "InterpreterUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Type.h"
 #include "clang/Interpreter/Interpreter.h"
@@ -222,6 +223,7 @@ void Value::clear() {
   OpaqueType = nullptr;
   Interp = nullptr;
   IsManuallyAlloc = false;
+  Name = "";
 }
 
 Value::~Value() { clear(); }
@@ -241,7 +243,7 @@ Interpreter &Value::getInterpreter() {
   return *Interp;
 }
 
-const Interpreter &Value::getInterpreter() const {
+Interpreter &Value::getInterpreter() const {
   assert(Interp != nullptr &&
          "Can't get interpreter from a default constructed value");
   return *Interp;
@@ -256,14 +258,17 @@ const ASTContext &Value::getASTContext() const {
 void Value::dump() const { print(llvm::outs()); }
 
 void Value::printType(llvm::raw_ostream &Out) const {
-  Out << "Not implement yet.\n";
+  Out << "(" << GetFullTypeName(getASTContext(), getType()) << ")\n";
 }
+
 void Value::printData(llvm::raw_ostream &Out) const {
-  Out << "Not implement yet.\n";
+  Out << printValueInternal() << "\n";
 }
+
 void Value::print(llvm::raw_ostream &Out) const {
   assert(OpaqueType != nullptr && "Can't print default Value");
-  Out << "Not implement yet.\n";
+  Out << "(" << GetFullTypeName(getASTContext(), getType()) << ")" << ' '
+      << printValueInternal() << "\n";
 }
 
 } // namespace clang
diff --git a/clang/lib/Interpreter/ValuePrinter.cpp b/clang/lib/Interpreter/ValuePrinter.cpp
new file mode 100644
index 00000000000000..19b9dcd3d89504
--- /dev/null
+++ b/clang/lib/Interpreter/ValuePrinter.cpp
@@ -0,0 +1,751 @@
+//===--- ValuePrinter.cpp - Value Printer -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements some value printer functions for clang-repl.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Interpreter/Interpreter.h"
+#include "clang/Interpreter/Value.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ParsedAttr.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/Orc/LLJIT.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_os_ostream.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "InterpreterUtils.h"
+
+#include <cassert>
+#include <codecvt>
+#include <cstddef>
+#include <cstdint>
+#include <locale>
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+namespace clang {
+
+std::string printAddress(const void *Ptr, const char Prefix = 0) {
+  if (!Ptr) {
+    return "nullptr";
+  }
+  std::ostringstream ostr;
+  if (Prefix) {
+    ostr << Prefix;
+  }
+  ostr << Ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const void *ptr) { return printAddress(ptr, '@'); }
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const void **ptr) { return printAddress(*ptr); }
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const bool *ptr) { return *ptr ? "true" : "false"; }
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const char *ptr) {
+  std::string value = "'";
+  switch (*ptr) {
+  case '\t':
+    value += "\\t";
+    break;
+  case '\n':
+    value += "\\n";
+    break;
+  case '\r':
+    value += "\\r";
+    break;
+  case '\f':
+    value += "\\f";
+    break;
+  case '\v':
+    value += "\\v";
+    break;
+  default:
+    value += *ptr;
+  }
+  value += "'";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const signed char *ptr) {
+  std::string value = "'";
+  switch (*ptr) {
+  case '\t':
+    value += "\\t";
+    break;
+  case '\n':
+    value += "\\n";
+    break;
+  case '\r':
+    value += "\\r";
+    break;
+  case '\f':
+    value += "\\f";
+    break;
+  case '\v':
+    value += "\\v";
+    break;
+  default:
+    value += *ptr;
+  }
+  value += "'";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const unsigned char *ptr) {
+  std::string value = "'";
+  switch (*ptr) {
+  case '\t':
+    value += "\\t";
+    break;
+  case '\n':
+    value += "\\n";
+    break;
+  case '\r':
+    value += "\\r";
+    break;
+  case '\f':
+    value += "\\f";
+    break;
+  case '\v':
+    value += "\\v";
+    break;
+  default:
+    value += *ptr;
+  }
+  value += "'";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const wchar_t *ptr) {
+  std::string value = "'";
+  switch (*ptr) {
+  case '\t':
+    value += "\\t";
+    break;
+  case '\n':
+    value += "\\n";
+    break;
+  case '\r':
+    value += "\\r";
+    break;
+  case '\f':
+    value += "\\f";
+    break;
+  case '\v':
+    value += "\\v";
+    break;
+  default:
+    value += *ptr;
+  }
+  value += "'";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const char16_t *ptr) {
+  std::string value = "'";
+  switch (*ptr) {
+  case '\t':
+    value += "\\t";
+    break;
+  case '\n':
+    value += "\\n";
+    break;
+  case '\r':
+    value += "\\r";
+    break;
+  case '\f':
+    value += "\\f";
+    break;
+  case '\v':
+    value += "\\v";
+    break;
+  default:
+    value += *ptr;
+  }
+  value += "'";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const char32_t *ptr) {
+  std::string value = "'";
+  switch (*ptr) {
+  case '\t':
+    value += "\\t";
+    break;
+  case '\n':
+    value += "\\n";
+    break;
+  case '\r':
+    value += "\\r";
+    break;
+  case '\f':
+    value += "\\f";
+    break;
+  case '\v':
+    value += "\\v";
+    break;
+  default:
+    value += *ptr;
+  }
+  value += "'";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const unsigned short *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const short *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const unsigned int *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const int *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const unsigned long *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const long *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const unsigned long long *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const long long *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const float *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const double *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const long double *ptr) {
+  std::ostringstream ostr;
+  ostr << *ptr;
+  return ostr.str();
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(char *ptr, bool seq) {
+  std::string value = "\"";
+  char *p = ptr;
+  while (*p != '\0') {
+    value += *p;
+    p++;
+  }
+  value += "\"";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(signed char *ptr, bool seq) {
+  std::string value = "\"";
+  signed char *p = ptr;
+  while (*p != '\0') {
+    value += *p;
+    p++;
+  }
+  value += "\"";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(unsigned char *ptr, bool seq) {
+  std::string value = "\"";
+  unsigned char *p = ptr;
+  while (*p != '\0') {
+    value += *p;
+    p++;
+  }
+  value += "\"";
+  return value;
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(wchar_t *ptr, bool seq) {
+  std::wstring value;
+  wchar_t *p = ptr;
+  while (*p != '\0') {
+    value += *p;
+    p++;
+  }
+  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
+  return "\"" + converter.to_bytes(value) + "\"";
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(char16_t *ptr, bool seq) {
+  std::u16string value;
+  char16_t *p = ptr;
+  while (*p != '\0') {
+    value += *p;
+    p++;
+  }
+  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
+  return "\"" + converter.to_bytes(value) + "\"";
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(char32_t *ptr, bool seq) {
+  std::u32string value;
+  char32_t *p = ptr;
+  while (*p != '\0') {
+    value += *p;
+    p++;
+  }
+  std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
+  return "\"" + converter.to_bytes(value) + "\"";
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const std::string *ptr) { return "\"" + *ptr + "\""; }
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const std::wstring *ptr) {
+  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
+  return "\"" + converter.to_bytes(*ptr) + "\"";
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const std::u16string *ptr) {
+  std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
+  return "\"" + converter.to_bytes(*ptr) + "\"";
+}
+
+REPL_EXTERNAL_VISIBILITY
+std::string printValue(const std::u32string *ptr) {
+  std::wstring_convert<std::codecvt_utf8_utf16<char32_t>, char32_t> converter;
+  return "\"" + converter.to_bytes(*ptr) + "\"";
+}
+
+std::string printBuiltinTypeValue(const Value &V, BuiltinType::Kind Kind) {
+  switch (Kind) {
+  case BuiltinType::Bool:
+    return V.convertTo<bool>() ? "true" : "false";
+  case BuiltinType::Char_U:
+  case BuiltinType::UChar: {
+    auto val = V.convertTo<unsigned char>();
+    return printValue(&val);
+  }
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar: {
+    auto val = V.convertTo<signed char>();
+    return printValue(&val);
+  }
+  case BuiltinType::WChar_S: {
+    auto val = V.convertTo<wchar_t>();
+    return printValue(&val);
+  }
+  case BuiltinType::Char16: {
+    auto val = V.convertTo<char16_t>();
+    return printValue(&val);
+  }
+  case BuiltinType::Char32: {
+    auto val = V.convertTo<char32_t>();
+    return printValue(&val);
+  }
+  case BuiltinType::UShort:
+    return std::to_string(V.convertTo<unsigned short>());
+  case BuiltinType::Short:
+    return std::to_string(V.convertTo<short>());
+  case BuiltinType::UInt:
+    return std::to_string(V.convertTo<unsigned int>());
+  case BuiltinType::Int:
+    return std::to_string(V.convertTo<int>());
+  case BuiltinType::ULong:
+    return std::to_string(V.convertTo<unsigned long>());
+  case BuiltinType::Long:
+    return std::to_string(V.convertTo<long>());
+  case BuiltinType::ULongLong:
+    return std::to_string(V.convertTo<unsigned long long>());
+  case BuiltinType::LongLong:
+    return std::to_string(V.convertTo<long long>());
+  case BuiltinType::Float:
+    return std::to_string(V.convertTo<float>());
+  case BuiltinType::Double:
+    return std::to_string(V.convertTo<double>());
+  case BuiltinType::LongDouble:
+    return std::to_string(V.convertTo<long double>());
+  default:
+    break;
+  }
+  return "";
+}
+
+std::string printValueByPtr(void *Ptr, QualType Type, uint64_t Offset) {
+  if (const BuiltinType *bt =
+          llvm::dyn_cast<BuiltinType>(Type.getCanonicalType().getTypePtr())) {
+    std::ostringstream os;
+    Ptr = (void *)((char *)Ptr + Offset);
+    switch (bt->getKind()) {
+    case BuiltinType::Bool:
+      return printValue((bool *)Ptr);
+    case BuiltinType::Char_U:
+      return printValue((unsigned char *)Ptr);
+    case BuiltinType::UChar:
+      return printValue((unsigned char *)Ptr);
+    case BuiltinType::Char_S:
+      return printValue((signed char *)Ptr);
+    case BuiltinType::SChar:
+      return printValue((signed char *)Ptr);
+    case BuiltinType::WChar_S:
+      return printValue((wchar_t *)Ptr);
+    case BuiltinType::Char16:
+      return printValue((char16_t *)Ptr);
+    case BuiltinType::Char32:
+      return printValue((char32_t *)Ptr);
+    case BuiltinType::UShort:
+      return printValue((unsigned short *)Ptr);
+    case BuiltinType::Short:
+      return printValue((short *)Ptr);
+    case BuiltinType::UInt:
+      return printValue((unsigned int *)Ptr);
+    case BuiltinType::Int:
+      return printValue((int *)Ptr);
+    case BuiltinType::ULong:
+      return printValue((unsigned long *)Ptr);
+    case BuiltinType::Long:
+      return printValue((long *)Ptr);
+    case BuiltinType::ULongLong:
+      return printValue((unsigned long long *)Ptr);
+    case BuiltinType::LongLong:
+      return printValue((long long *)Ptr);
+    case BuiltinType::Float:
+      return printValue((float *)Ptr);
+    case BuiltinType::Double:
+      return printValue((double *)Ptr);
+    case BuiltinType::LongDouble:
+      return printValue((long double *)Ptr);
+    default:
+      break;
+    }
+  }
+  if (!Ptr) {
+    return "nullptr";
+  }
+  return printAddress(Ptr, '@');
+}
+
+std::string printEnumValue(const Value &V, QualType Type) {
+  std::ostringstream ostr;
+  const ASTContext &C = V.getASTContext();
+  const EnumType *EnumTy = Type->getAs<EnumType>();
+  assert(EnumTy && "printEnumValue invoked for a non enum type");
+  EnumDecl *decl = EnumTy->getDecl();
+  uint64_t value = V.getULongLong();
+  bool isFirst = true;
+  llvm::APSInt valAsAPSInt = C.MakeIntValue(value, Type);
+  for (EnumDecl::enumerator_iterator I = decl->enumerator_begin(),
+          ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/88729


More information about the cfe-commits mailing list