llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: None (cmtice)

<details>
<summary>Changes</summary>

This adds basic c-style type casting to DIL. It handles basic built-in types: 
bool, char, short, int, long, double, float, and void. It also handles 
user-defined types (e.g. class names, typedefs, etc.). It does NOT handle C++ 
templates at the moment. Not sure if this is something we would want to add to 
DIL later or not. DIL will not be supporting C++-specific-style casts 
(static_cast&lt;&gt;, reinterpret_cast&lt;&gt;, or dynamic_cast&lt;&gt;).

This PR adds quite a bit of type-parsing, which must happen in the parser, to 
resolve ambiguity ("is this thing I'm looking at a type cast or just an 
expression in parentheses?").

I'd be happy to break this up into smaller PRs if someone could suggest a 
reasonable way to break it up.

---

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


11 Files Affected:

- (modified) lldb/docs/dil-expr-lang.ebnf (+30-2) 
- (modified) lldb/include/lldb/ValueObject/DILAST.h (+41) 
- (modified) lldb/include/lldb/ValueObject/DILEval.h (+7) 
- (modified) lldb/include/lldb/ValueObject/DILParser.h (+133) 
- (modified) lldb/source/ValueObject/DILAST.cpp (+4) 
- (modified) lldb/source/ValueObject/DILEval.cpp (+273-12) 
- (modified) lldb/source/ValueObject/DILParser.cpp (+630-4) 
- (modified) 
lldb/test/API/commands/frame/var-dil/basics/LocalVars/TestFrameVarDILLocalVars.py
 (+1) 
- (added) lldb/test/API/commands/frame/var-dil/expr/CStyleCast/Makefile (+6) 
- (added) 
lldb/test/API/commands/frame/var-dil/expr/CStyleCast/TestFrameVarDILCStyleCast.py
 (+233) 
- (added) lldb/test/API/commands/frame/var-dil/expr/CStyleCast/main.cpp (+81) 


``````````diff
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index 67328939ba420..4a66734e75fec 100644
--- a/lldb/docs/dil-expr-lang.ebnf
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -3,10 +3,13 @@
 (* This is currently a subset of the final DIL Language, matching the current
    DIL implementation. *)
 
-expression = unary_expression ;
+expression = cast_expression;
+
+cast_expression = unary_expression
+                | "(" type_id ")" cast_expression;
 
 unary_expression = postfix_expression
-                 | unary_operator expression ;
+                 | unary_operator cast_expression ;
 
 unary_operator = "*" | "&" ;
 
@@ -41,6 +44,31 @@ nested_name_specifier = type_name "::"
                       | namespace_name '::'
                       | nested_name_specifier identifier "::" ;
 
+type_id = type_specifier_seq [abstract_declarator] ;
+
+type_specifier_seq = type_specifier [type_specifier];
+
+type_specifier = ["::"] [nested_name_specifier] type_name;
+               | "char"
+               | "bool"
+               | "short"
+               | "int"
+               | "long"
+               | "signed"
+               | "unsigned"
+               | "float"
+               | "double"
+               | "void" ;
+
+nested_name_specifier = type_name "::"
+                      | namespace_name "::"
+                      | nested_name_specifier identifier "::" ;
+
+abstract_declarator = ptr_operator [abstract_declarator] ;
+
+ptr_operator = "*"
+             | "&";
+
 type_name = class_name
           | enum_name
           | typedef_name;
diff --git a/lldb/include/lldb/ValueObject/DILAST.h 
b/lldb/include/lldb/ValueObject/DILAST.h
index 1d10755c46e39..bbaad28d55735 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -20,6 +20,7 @@ namespace lldb_private::dil {
 enum class NodeKind {
   eArraySubscriptNode,
   eBitExtractionNode,
+  eCStyleCastNode,
   eErrorNode,
   eFloatLiteralNode,
   eIdentifierNode,
@@ -28,6 +29,21 @@ enum class NodeKind {
   eUnaryOpNode,
 };
 
+/// The C-Style casts allowed by DIL.
+enum class CStyleCastKind {
+  eEnumeration,
+  eNullptr,
+  eReference,
+  eNone,
+};
+
+/// Promotions for C-Style casts in DIL.
+enum class CastPromoKind {
+  eArithmetic,
+  ePointer,
+  eNone,
+};
+
 /// The Unary operators recognized by DIL.
 enum class UnaryOpKind {
   AddrOf, // "&"
@@ -226,6 +242,29 @@ class FloatLiteralNode : public ASTNode {
   llvm::APFloat m_value;
 };
 
+class CStyleCastNode : public ASTNode {
+public:
+  CStyleCastNode(uint32_t location, CompilerType type, ASTNodeUP operand,
+                 CStyleCastKind kind)
+      : ASTNode(location, NodeKind::eCStyleCastNode), m_type(type),
+        m_operand(std::move(operand)), m_cast_kind(kind) {}
+
+  llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
+
+  CompilerType GetType() const { return m_type; }
+  ASTNode *GetOperand() const { return m_operand.get(); }
+  CStyleCastKind GetCastKind() const { return m_cast_kind; }
+
+  static bool classof(const ASTNode *node) {
+    return node->GetKind() == NodeKind::eCStyleCastNode;
+  }
+
+private:
+  CompilerType m_type;
+  ASTNodeUP m_operand;
+  CStyleCastKind m_cast_kind;
+};
+
 /// This class contains one Visit method for each specialized type of
 /// DIL AST node. The Visit methods are used to dispatch a DIL AST node to
 /// the correct function in the DIL expression evaluator for evaluating that
@@ -247,6 +286,8 @@ class Visitor {
   Visit(const IntegerLiteralNode *node) = 0;
   virtual llvm::Expected<lldb::ValueObjectSP>
   Visit(const FloatLiteralNode *node) = 0;
+  virtual llvm::Expected<lldb::ValueObjectSP>
+  Visit(const CStyleCastNode *node) = 0;
 };
 
 } // namespace lldb_private::dil
diff --git a/lldb/include/lldb/ValueObject/DILEval.h 
b/lldb/include/lldb/ValueObject/DILEval.h
index 5a48c2c989f4d..3d4ef021cbc6f 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -58,12 +58,19 @@ class Interpreter : Visitor {
   Visit(const IntegerLiteralNode *node) override;
   llvm::Expected<lldb::ValueObjectSP>
   Visit(const FloatLiteralNode *node) override;
+  llvm::Expected<lldb::ValueObjectSP>
+  Visit(const CStyleCastNode *node) override;
 
   llvm::Expected<CompilerType>
   PickIntegerType(lldb::TypeSystemSP type_system,
                   std::shared_ptr<ExecutionContextScope> ctx,
                   const IntegerLiteralNode *literal);
 
+  llvm::Expected<CompilerType>
+  VerifyCStyleCastType(lldb::ValueObjectSP &operand, CompilerType &op_type,
+                       CompilerType target_type, CastPromoKind &promo_kind,
+                       CStyleCastKind &cast_kind, int location);
+
   // Used by the interpreter to create objects, perform casts, etc.
   lldb::TargetSP m_target;
   llvm::StringRef m_expr;
diff --git a/lldb/include/lldb/ValueObject/DILParser.h 
b/lldb/include/lldb/ValueObject/DILParser.h
index 90df109337dcf..081711d26439d 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -10,6 +10,7 @@
 #define LLDB_VALUEOBJECT_DILPARSER_H
 
 #include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrame.h"
 #include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/ValueObject/DILAST.h"
@@ -31,6 +32,9 @@ enum class ErrorCode : unsigned char {
   kUnknown,
 };
 
+llvm::Expected<lldb::TypeSystemSP>
+DILGetTypeSystemFromCU(std::shared_ptr<StackFrame> ctx);
+
 // The following is modeled on class OptionParseError.
 class DILDiagnosticError
     : public llvm::ErrorInfo<DILDiagnosticError, DiagnosticError> {
@@ -55,6 +59,61 @@ class DILDiagnosticError
 
   std::string message() const override { return m_detail.rendered; }
 };
+/// TypeDeclaration builds information about the literal type definition as
+/// type is being parsed. It doesn't perform semantic analysis for non-basic
+/// types -- e.g. "char&&&" is a valid type declaration.
+/// NOTE: CV qualifiers are ignored.
+class TypeDeclaration {
+public:
+  enum class TypeSpecifier {
+    kBool,
+    kChar,
+    kDouble,
+    kFloat,
+    kInt,
+    kLong,
+    kLongDouble,
+    kLongLong,
+    kShort,
+    kUnknown,
+    kVoid,
+  };
+
+  enum class SignSpecifier {
+    kUnknown,
+    kSigned,
+    kUnsigned,
+  };
+
+  bool IsEmpty() const { return !m_is_builtin && !m_is_user_type; }
+
+  lldb::BasicType GetBasicType() const;
+
+public:
+  // Indicates user-defined typename (e.g. "MyClass", "MyTmpl<int>").
+  std::string m_user_typename;
+
+  // Basic type specifier ("void", "char", "intr", "float", "long long", etc.).
+  TypeSpecifier m_type_specifier = TypeSpecifier::kUnknown;
+
+  // Signedness specifier ("signed", "unsigned").
+  SignSpecifier m_sign_specifier = SignSpecifier::kUnknown;
+
+  // Does the type declaration includes "int" specifier?
+  // This is different than `type_specifier_` and is used to detect "int"
+  // duplication for types that can be combined with "int" specifier (e.g.
+  // "short int", "long int").
+  bool m_has_int_specifier = false;
+
+  // Indicates whether there was an error during parsing.
+  bool m_has_error = false;
+
+  // Indicates whether this declaration describes a builtin type.
+  bool m_is_builtin = false;
+
+  // Indicates whether this declaration describes a user type.
+  bool m_is_user_type = false;
+}; // class TypeDeclaration
 
 /// Pure recursive descent parser for C++ like expressions.
 /// EBNF grammar for the parser is described in lldb/docs/dil-expr-lang.ebnf
@@ -100,10 +159,22 @@ class DILParser {
   ASTNodeUP ParseIntegerLiteral();
   ASTNodeUP ParseFloatingPointLiteral();
 
+  ASTNodeUP ParseCastExpression();
+  std::optional<CompilerType> ParseTypeId(bool must_be_type_id = false);
+  void ParseTypeSpecifierSeq(TypeDeclaration *type_decl);
+  bool ParseTypeSpecifier(TypeDeclaration *type_decl);
+  std::string ParseTypeName();
+  CompilerType ResolveTypeDeclarators(CompilerType type,
+                                      const std::vector<Token> &ptr_operators);
+  bool IsSimpleTypeSpecifierKeyword(Token token) const;
+  bool HandleSimpleTypeSpecifier(TypeDeclaration *type_decl);
+
   void BailOut(const std::string &error, uint32_t loc, uint16_t err_len);
 
   void Expect(Token::Kind kind);
 
+  void ExpectOneOf(std::vector<Token::Kind> kinds_vec);
+
   void TentativeParsingRollback(uint32_t saved_idx) {
     if (m_error)
       llvm::consumeError(std::move(m_error));
@@ -132,4 +203,66 @@ class DILParser {
 
 } // namespace lldb_private::dil
 
+namespace llvm {
+template <>
+struct format_provider<lldb_private::dil::TypeDeclaration::TypeSpecifier> {
+  static void format(const lldb_private::dil::TypeDeclaration::TypeSpecifier 
&t,
+                     raw_ostream &OS, llvm::StringRef Options) {
+    switch (t) {
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kVoid:
+      OS << "void";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kBool:
+      OS << "bool";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kChar:
+      OS << "char";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kInt:
+      OS << "int";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kFloat:
+      OS << "float";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kShort:
+      OS << "short";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kLong:
+      OS << "long";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kLongLong:
+      OS << "long long";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kDouble:
+      OS << "double";
+      break;
+    case lldb_private::dil::TypeDeclaration::TypeSpecifier::kLongDouble:
+      OS << "long double";
+      break;
+    default:
+      OS << "invalid type specifier";
+      break;
+    }
+  }
+};
+
+template <>
+struct format_provider<lldb_private::dil::TypeDeclaration::SignSpecifier> {
+  static void format(const lldb_private::dil::TypeDeclaration::SignSpecifier 
&t,
+                     raw_ostream &OS, llvm::StringRef Options) {
+    switch (t) {
+    case lldb_private::dil::TypeDeclaration::SignSpecifier::kSigned:
+      OS << "signed";
+      break;
+    case lldb_private::dil::TypeDeclaration::SignSpecifier::kUnsigned:
+      OS << "unsigned";
+      break;
+    default:
+      OS << "invalid sign specifier";
+      break;
+    }
+  }
+};
+} // namespace llvm
+
 #endif // LLDB_VALUEOBJECT_DILPARSER_H
diff --git a/lldb/source/ValueObject/DILAST.cpp 
b/lldb/source/ValueObject/DILAST.cpp
index 70564663a62cd..f8afd9d7bd50a 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -46,4 +46,8 @@ llvm::Expected<lldb::ValueObjectSP> 
FloatLiteralNode::Accept(Visitor *v) const {
   return v->Visit(this);
 }
 
+llvm::Expected<lldb::ValueObjectSP> CStyleCastNode::Accept(Visitor *v) const {
+  return v->Visit(this);
+}
+
 } // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index c6cf41ee9e9ee..05bcc25d2b9f2 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
 #include "lldb/ValueObject/ValueObject.h"
 #include "lldb/ValueObject/ValueObjectRegister.h"
 #include "lldb/ValueObject/ValueObjectVariable.h"
@@ -21,6 +22,42 @@
 
 namespace lldb_private::dil {
 
+lldb::ValueObjectSP
+GetDynamicOrSyntheticValue(lldb::ValueObjectSP in_valobj_sp,
+                           lldb::DynamicValueType use_dynamic,
+                           bool use_synthetic) {
+  Status error;
+  if (!in_valobj_sp) {
+    error = Status("invalid value object");
+    return in_valobj_sp;
+  }
+  lldb::ValueObjectSP value_sp = in_valobj_sp;
+  Target *target = value_sp->GetTargetSP().get();
+  // If this ValueObject holds an error, then it is valuable for that.
+  if (value_sp->GetError().Fail())
+    return value_sp;
+
+  if (!target)
+    return lldb::ValueObjectSP();
+
+  if (use_dynamic != lldb::eNoDynamicValues) {
+    lldb::ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(use_dynamic);
+    if (dynamic_sp)
+      value_sp = dynamic_sp;
+  }
+
+  if (use_synthetic) {
+    lldb::ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
+    if (synthetic_sp)
+      value_sp = synthetic_sp;
+  }
+
+  if (!value_sp)
+    error = Status("invalid value object");
+
+  return value_sp;
+}
+
 static lldb::VariableSP DILFindVariable(ConstString name,
                                         VariableList &variable_list) {
   lldb::VariableSP exact_match;
@@ -499,16 +536,6 @@ Interpreter::Visit(const BitFieldExtractionNode *node) {
   return child_valobj_sp;
 }
 
-static llvm::Expected<lldb::TypeSystemSP>
-GetTypeSystemFromCU(std::shared_ptr<StackFrame> ctx) {
-  SymbolContext symbol_context =
-      ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
-  lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
-
-  symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
-  return symbol_context.module_sp->GetTypeSystemForLanguage(language);
-}
-
 static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
                                  lldb::BasicType basic_type) {
   if (type_system)
@@ -559,7 +586,7 @@ Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,
 llvm::Expected<lldb::ValueObjectSP>
 Interpreter::Visit(const IntegerLiteralNode *node) {
   llvm::Expected<lldb::TypeSystemSP> type_system =
-      GetTypeSystemFromCU(m_exe_ctx_scope);
+      DILGetTypeSystemFromCU(m_exe_ctx_scope);
   if (!type_system)
     return type_system.takeError();
 
@@ -583,7 +610,7 @@ Interpreter::Visit(const IntegerLiteralNode *node) {
 llvm::Expected<lldb::ValueObjectSP>
 Interpreter::Visit(const FloatLiteralNode *node) {
   llvm::Expected<lldb::TypeSystemSP> type_system =
-      GetTypeSystemFromCU(m_exe_ctx_scope);
+      DILGetTypeSystemFromCU(m_exe_ctx_scope);
   if (!type_system)
     return type_system.takeError();
 
@@ -602,4 +629,238 @@ Interpreter::Visit(const FloatLiteralNode *node) {
                                                   "result");
 }
 
+llvm::Expected<CompilerType> Interpreter::VerifyCStyleCastType(
+    lldb::ValueObjectSP &operand, CompilerType &op_type,
+    CompilerType target_type, CastPromoKind &promo_kind,
+    CStyleCastKind &cast_kind, int location) {
+
+  promo_kind = CastPromoKind::eNone;
+  if (op_type.IsReferenceType())
+    op_type = op_type.GetNonReferenceType();
+  if (target_type.IsScalarType()) {
+    if (op_type.IsArrayType()) {
+      // Do array-to-pointer conversion.
+      CompilerType deref_type =
+          op_type.IsReferenceType() ? op_type.GetNonReferenceType() : op_type;
+      CompilerType result_type =
+          deref_type.GetArrayElementType(nullptr).GetPointerType();
+      uint64_t addr = operand->GetLoadAddress();
+      llvm::StringRef name = operand->GetName().GetStringRef();
+      operand = ValueObject::CreateValueObjectFromAddress(
+          name, addr, m_exe_ctx_scope, result_type, /*do_deref=*/false);
+      op_type = result_type;
+    }
+
+    if (op_type.IsPointerType() || op_type.IsNullPtrType()) {
+      // C-style cast from pointer to float/double is not allowed.
+      if (target_type.IsFloat()) {
+        std::string errMsg = llvm::formatv(
+            "C-style cast from {0} to {1} is not allowed",
+            op_type.TypeDescription(), target_type.TypeDescription());
+        return llvm::make_error<DILDiagnosticError>(
+            m_expr, std::move(errMsg), location,
+            op_type.TypeDescription().length());
+      }
+      // Casting pointer to bool is valid. Otherwise check if the result type
+      // is at least as big as the pointer size.
+      uint64_t type_byte_size = 0;
+      uint64_t rhs_type_byte_size = 0;
+      if (auto temp = target_type.GetByteSize(m_exe_ctx_scope.get()))
+        // type_byte_size = temp.value();
+        type_byte_size = *temp;
+      if (auto temp = op_type.GetByteSize(m_exe_ctx_scope.get()))
+        // rhs_type_byte_size = temp.value();
+        rhs_type_byte_size = *temp;
+      if (!target_type.IsBoolean() && type_byte_size < rhs_type_byte_size) {
+        std::string errMsg = llvm::formatv(
+            "cast from pointer to smaller type {0} loses information",
+            target_type.TypeDescription());
+        return llvm::make_error<DILDiagnosticError>(
+            m_expr, std::move(errMsg), location,
+            op_type.TypeDescription().length());
+      }
+    } else if (!op_type.IsScalarType() && !op_type.IsEnumerationType()) {
+      // Otherwise accept only arithmetic types and enums.
+      std::string errMsg = llvm::formatv(
+          "cannot convert {0} to {1} without a conversion operator",
+          op_type.TypeDescription(), target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    promo_kind = CastPromoKind::eArithmetic;
+  } else if (target_type.IsEnumerationType()) {
+    // Cast to enum type.
+    if (!op_type.IsScalarType() && !op_type.IsEnumerationType()) {
+      std::string errMsg = llvm::formatv(
+          "C-style cast from {0} to {1} is not allowed",
+          op_type.TypeDescription(), target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    cast_kind = CStyleCastKind::eEnumeration;
+
+  } else if (target_type.IsPointerType()) {
+    if (!op_type.IsInteger() && !op_type.IsEnumerationType() &&
+        !op_type.IsArrayType() && !op_type.IsPointerType() &&
+        !op_type.IsNullPtrType()) {
+      std::string errMsg = llvm::formatv(
+          "cannot cast from type {0} to pointer type {1}",
+          op_type.TypeDescription(), target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    promo_kind = CastPromoKind::ePointer;
+
+  } else if (target_type.IsNullPtrType()) {
+    // Cast to nullptr type.
+    bool is_signed;
+    if (!target_type.IsNullPtrType() &&
+        (!operand->IsIntegerType(is_signed) ||
+         (is_signed && operand->GetValueAsSigned(0) != 0) ||
+         (!is_signed && operand->GetValueAsUnsigned(0) != 0))) {
+      std::string errMsg = llvm::formatv(
+          "C-style cast from {0} to {1} is not allowed",
+          op_type.TypeDescription(), target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    cast_kind = CStyleCastKind::eNullptr;
+
+  } else if (target_type.IsReferenceType()) {
+    // Cast to a reference type.
+    cast_kind = CStyleCastKind::eReference;
+  } else {
+    // Unsupported cast.
+    std::string errMsg =
+        llvm::formatv("casting of {0} to {1} is not implemented yet",
+                      op_type.TypeDescription(), 
target_type.TypeDescription());
+    return llvm::make_error<DILDiagnosticError>(
+        m_expr, std::move(errMsg), location,
+        op_type.TypeDescription().length());
+  }
+
+  return target_type;
+}
+
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::Visit(const CStyleCastNode *node) {
+  auto operand_or_err = Evaluate(node->GetOperand());
+  if (!operand_or_err)
+    return operand_or_err;
+
+  lldb::ValueObjectSP operand = *operand_or_err;
+  CompilerType op_type = operand->GetCompilerType();
+  CStyleCastKind cast_kind = CStyleCastKind::eNone;
+  CastPromoKind promo_kind = CastPromoKind::eNone;
+
+  auto type_or_err =
+      VerifyCStyleCastType(operand, op_type, node->GetType(), promo_kind,
+                           cast_kind, node->GetLocation());
+  if (!type_or_err)
+    return type_or_err.takeError();
+
+  CompilerType target_type = *type_or_err;
+  if (op_type.IsReferenceType()) {
+    Status error;
+    operand = operand->Dereference(error);
+    if (error.Fail())
+      return llvm::make_error<D...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/159500
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to