Skip to content
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

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

Closed
wants to merge 3 commits into from

Conversation

wlonestar
Copy link

No description provided.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Apr 15, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 15, 2024

@llvm/pr-subscribers-clang

Author: wlonestar (wlonestar)

Changes

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 --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]

@wlonestar wlonestar closed this Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants