jackoalan updated this revision to Diff 272288.
jackoalan marked an inline comment as done.
jackoalan added a comment.

Fix ternary to use corresponding float/double overloaded constructors of APFloat


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82160

Files:
  lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
  lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
  lldb/test/Shell/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
  lldb/test/Shell/SymbolFile/PDB/ast-restore.test
  llvm/include/llvm/DebugInfo/PDB/PDBTypes.h

Index: llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
===================================================================
--- llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H
 #define LLVM_DEBUGINFO_PDB_PDBTYPES_H
 
+#include "llvm/ADT/APFloat.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
 #include "llvm/DebugInfo/PDB/IPDBFrameData.h"
@@ -464,6 +465,88 @@
     char *String;
   } Value;
 
+  bool isIntegralType() const {
+    switch (Type) {
+    case Bool:
+    case Int8:
+    case Int16:
+    case Int32:
+    case Int64:
+    case UInt8:
+    case UInt16:
+    case UInt32:
+    case UInt64:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+#define VARIANT_WIDTH(Enum, NumBits)                                           \
+  case PDB_VariantType::Enum:                                                  \
+    return NumBits;
+
+  unsigned getBitWidth() const {
+    switch (Type) {
+      VARIANT_WIDTH(Bool, 1u)
+      VARIANT_WIDTH(Int8, 8u)
+      VARIANT_WIDTH(Int16, 16u)
+      VARIANT_WIDTH(Int32, 32u)
+      VARIANT_WIDTH(Int64, 64u)
+      VARIANT_WIDTH(Single, 32u)
+      VARIANT_WIDTH(Double, 64u)
+      VARIANT_WIDTH(UInt8, 8u)
+      VARIANT_WIDTH(UInt16, 16u)
+      VARIANT_WIDTH(UInt32, 32u)
+      VARIANT_WIDTH(UInt64, 64u)
+    default:
+      assert(false && "Variant::toAPSInt called on non-numeric type");
+      return 0u;
+    }
+  }
+
+#undef VARIANT_WIDTH
+
+#define VARIANT_APSINT(Enum, NumBits, IsUnsigned)                              \
+  case PDB_VariantType::Enum:                                                  \
+    return APSInt(APInt(NumBits, Value.Enum), IsUnsigned);
+
+  APSInt toAPSInt() const {
+    switch (Type) {
+      VARIANT_APSINT(Bool, 1u, true)
+      VARIANT_APSINT(Int8, 8u, false)
+      VARIANT_APSINT(Int16, 16u, false)
+      VARIANT_APSINT(Int32, 32u, false)
+      VARIANT_APSINT(Int64, 64u, false)
+      VARIANT_APSINT(UInt8, 8u, true)
+      VARIANT_APSINT(UInt16, 16u, true)
+      VARIANT_APSINT(UInt32, 32u, true)
+      VARIANT_APSINT(UInt64, 64u, true)
+    default:
+      assert(false && "Variant::toAPSInt called on non-integral type");
+      return APSInt();
+    }
+  }
+
+#undef VARIANT_APSINT
+
+  APFloat toAPFloat() const {
+    // Float constants may be tagged as integers.
+    switch (Type) {
+    case PDB_VariantType::Single:
+    case PDB_VariantType::UInt32:
+    case PDB_VariantType::Int32:
+      return APFloat(Value.Single);
+    case PDB_VariantType::Double:
+    case PDB_VariantType::UInt64:
+    case PDB_VariantType::Int64:
+      return APFloat(Value.Double);
+    default:
+      assert(false && "Variant::toAPFloat called on non-floating-point type");
+      return APFloat::getZero(APFloat::IEEEsingle());
+    }
+  }
+
 #define VARIANT_EQUAL_CASE(Enum)                                               \
   case PDB_VariantType::Enum:                                                  \
     return Value.Enum == Other.Value.Enum;
Index: lldb/test/Shell/SymbolFile/PDB/ast-restore.test
===================================================================
--- lldb/test/Shell/SymbolFile/PDB/ast-restore.test
+++ lldb/test/Shell/SymbolFile/PDB/ast-restore.test
@@ -46,6 +46,12 @@
 CLASS:         class Class : public N0::N1::Base {
 CLASS-DAG:             const N0::N1::(anonymous namespace)::Enum m_ce;
 CLASS-DAG:             static int ClassStatic;
+CLASS-DAG:             static const int ClassStaticConst = 8;
+CLASS-DAG:             static const int ClassStaticConstexpr = 9;
+CLASS-DAG:             static const float ClassStaticConstexprFloat = 10.F;
+CLASS-DAG:             static const double ClassStaticConstexprDouble = 11.;
+CLASS-DAG:             static const double ClassStaticConstexprLongDouble = 12.;
+CLASS-DAG:             static const N0::N1::(anonymous namespace)::Enum ClassStaticConstEnum = 8;
 CLASS-DAG:             N0::N1::Class::Inner m_inner;
 CLASS-DAG:             {{(inline )?}}Class(N0::N1::(anonymous namespace)::Enum);
 CLASS-DAG:             static {{(inline )?}}int StaticFunc(const N0::N1::Class &);
Index: lldb/test/Shell/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
===================================================================
--- lldb/test/Shell/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
+++ lldb/test/Shell/SymbolFile/PDB/Inputs/AstRestoreTest.cpp
@@ -22,6 +22,12 @@
   const Enum m_ce;
 
   static int ClassStatic;
+  static const int ClassStaticConst = 8;
+  static constexpr int ClassStaticConstexpr = 9;
+  static constexpr float ClassStaticConstexprFloat = 10.f;
+  static constexpr double ClassStaticConstexprDouble = 11.0;
+  static constexpr long double ClassStaticConstexprLongDouble = 12.0;
+  static const Enum ClassStaticConstEnum = Enum_3;
 
 private:
   struct Inner {
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -873,6 +873,24 @@
                                                  const CompilerType &var_type,
                                                  lldb::AccessType access);
 
+  /// Initializes a variable with an integer value.
+  /// \param var The variable to initialize. Must not already have an
+  ///            initializer and must have an integer or enum type.
+  /// \param init_value The integer value that the variable should be
+  ///                   initialized to. Has to match the bit width of the
+  ///                   variable type.
+  static void SetIntegerInitializerForVariable(clang::VarDecl *var,
+                                               const llvm::APInt &init_value);
+
+  /// Initializes a variable with a floating point value.
+  /// \param var The variable to initialize. Must not already have an
+  ///            initializer and must have a floating point type.
+  /// \param init_value The float value that the variable should be
+  ///                   initialized to.
+  static void
+  SetFloatingInitializerForVariable(clang::VarDecl *var,
+                                    const llvm::APFloat &init_value);
+
   clang::CXXMethodDecl *AddMethodToCXXRecordType(
       lldb::opaque_compiler_type_t type, llvm::StringRef name,
       const char *mangled_name, const CompilerType &method_type,
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -7313,6 +7313,35 @@
   return var_decl;
 }
 
+void TypeSystemClang::SetIntegerInitializerForVariable(
+    VarDecl *var, const llvm::APInt &init_value) {
+  assert(!var->hasInit() && "variable already initialized");
+
+  clang::ASTContext &ast = var->getASTContext();
+  QualType qt = var->getType();
+  assert(qt->isIntegralOrEnumerationType() &&
+         "only integer or enum types supported");
+  // If the variable is an enum type, take the underlying integer type as
+  // the type of the integer literal.
+  if (const EnumType *enum_type = llvm::dyn_cast<EnumType>(qt.getTypePtr())) {
+    const EnumDecl *enum_decl = enum_type->getDecl();
+    qt = enum_decl->getIntegerType();
+  }
+  var->setInit(IntegerLiteral::Create(ast, init_value, qt.getUnqualifiedType(),
+                                      SourceLocation()));
+}
+
+void TypeSystemClang::SetFloatingInitializerForVariable(
+    clang::VarDecl *var, const llvm::APFloat &init_value) {
+  assert(!var->hasInit() && "variable already initialized");
+
+  clang::ASTContext &ast = var->getASTContext();
+  QualType qt = var->getType();
+  assert(qt->isFloatingType() && "only floating point types supported");
+  var->setInit(FloatingLiteral::Create(
+      ast, init_value, true, qt.getUnqualifiedType(), SourceLocation()));
+}
+
 clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
     lldb::opaque_compiler_type_t type, llvm::StringRef name,
     const char *mangled_name, const CompilerType &method_clang_type,
Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -1265,6 +1265,54 @@
       if (!decl)
         continue;
 
+      // Static constant members may be a const[expr] declaration.
+      // Query the symbol's value as the variable initializer if valid.
+      if (member_comp_type.IsConst()) {
+        auto value = member->getValue();
+        auto qual_type = decl->getType();
+        auto type_width = m_ast.getASTContext().getIntWidth(qual_type);
+        auto constant_width = value.getBitWidth();
+
+        if (qual_type->isIntegralOrEnumerationType()) {
+          if (type_width >= constant_width) {
+            TypeSystemClang::SetIntegerInitializerForVariable(
+                decl, value.toAPSInt().extOrTrunc(type_width));
+          } else if (Log *log_ast =
+              GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
+            LLDB_LOG(
+                log_ast,
+                "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
+                "which resolves to a wider constant value ({4} bits). "
+                "Ignoring constant.",
+                record_type.GetTypeName(), member_name,
+                member_comp_type.GetTypeName(), type_width, constant_width);
+          }
+        } else {
+          switch (member_comp_type.GetBasicTypeEnumeration()) {
+          case lldb::eBasicTypeFloat:
+          case lldb::eBasicTypeDouble:
+          case lldb::eBasicTypeLongDouble:
+            if (type_width == constant_width) {
+              TypeSystemClang::SetFloatingInitializerForVariable(
+                  decl, value.toAPFloat());
+            } else if (Log *log_ast = GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
+              LLDB_LOG(
+                  log_ast,
+                  "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) which "
+                  "resolves to a constant value of mismatched width ({4} bits). "
+                  "Ignoring constant.",
+                  record_type.GetTypeName(), member_name,
+                  member_comp_type.GetTypeName(), type_width, constant_width);
+            }
+            break;
+          default:
+            break;
+          }
+        }
+
+
+      }
+
       m_uid_to_decl[member->getSymIndexId()] = decl;
 
       break;
Index: lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -25,6 +25,7 @@
 namespace llvm {
 namespace pdb {
 class TpiStream;
+class GlobalsStream;
 }
 } // namespace llvm
 
@@ -33,6 +34,7 @@
 class CompilerType;
 namespace npdb {
 class PdbAstBuilder;
+class PdbIndex;
 
 class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
   using IndexedBase =
@@ -49,14 +51,14 @@
   CompilerType &m_derived_ct;
   clang::TagDecl &m_tag_decl;
   PdbAstBuilder &m_ast_builder;
-  llvm::pdb::TpiStream &m_tpi;
+  PdbIndex &m_index;
   std::vector<IndexedBase> m_bases;
   ClangASTImporter::LayoutInfo m_layout;
 
 public:
   UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct,
                      clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder,
-                     llvm::pdb::TpiStream &tpi);
+                     PdbIndex &index);
 
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
   llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR,            \
Index: lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -6,14 +6,17 @@
 #include "PdbUtil.h"
 
 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 
@@ -29,10 +32,10 @@
                                        CompilerType &derived_ct,
                                        clang::TagDecl &tag_decl,
                                        PdbAstBuilder &ast_builder,
-                                       TpiStream &tpi)
+                                       PdbIndex &index)
     : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
-      m_ast_builder(ast_builder), m_tpi(tpi) {
-  CVType cvt = m_tpi.getType(m_id.index);
+      m_ast_builder(ast_builder), m_index(index) {
+  CVType cvt = m_index.tpi().getType(m_id.index);
   switch (cvt.kind()) {
   case LF_ENUM:
     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er));
@@ -55,7 +58,7 @@
   PdbTypeSymId type_id(ti);
   clang::QualType qt = m_ast_builder.GetOrCreateType(type_id);
 
-  CVType udt_cvt = m_tpi.getType(ti);
+  CVType udt_cvt = m_index.tpi().getType(ti);
 
   std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
       m_ast_builder.clang().CreateBaseClassSpecifier(
@@ -128,9 +131,70 @@
 
   lldb::AccessType access =
       TranslateMemberAccess(static_data_member.getAccess());
-  TypeSystemClang::AddVariableToRecordType(
+  auto decl = TypeSystemClang::AddVariableToRecordType(
       m_derived_ct, static_data_member.Name, member_ct, access);
 
+  // Static constant members may be a const[expr] declaration.
+  // Query the symbol's value as the variable initializer if valid.
+  if (member_ct.IsConst()) {
+    auto qual_name = decl->getQualifiedNameAsString();
+
+    auto results =
+        m_index.globals().findRecordsByName(qual_name, m_index.symrecords());
+
+    for (const auto &result : results) {
+      if (result.second.kind() == SymbolKind::S_CONSTANT) {
+        ConstantSym constant(SymbolRecordKind::ConstantSym);
+        cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(result.second,
+                                                                constant));
+
+        auto qual_type = decl->getType();
+        auto type_width = decl->getASTContext().getIntWidth(qual_type);
+        auto constant_width = constant.Value.getBitWidth();
+
+        if (qual_type->isIntegralOrEnumerationType()) {
+          if (type_width >= constant_width) {
+            TypeSystemClang::SetIntegerInitializerForVariable(
+                decl, constant.Value.extOrTrunc(type_width));
+          } else if (Log *log_ast =
+              GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
+            LLDB_LOG(
+                log_ast,
+                "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
+                "which resolves to a wider constant value ({4} bits). "
+                "Ignoring constant.",
+                m_derived_ct.GetTypeName(), static_data_member.Name,
+                member_ct.GetTypeName(), type_width, constant_width);
+          }
+        } else {
+          auto basic_type_enum = member_ct.GetBasicTypeEnumeration();
+          switch (basic_type_enum) {
+          case lldb::eBasicTypeFloat:
+          case lldb::eBasicTypeDouble:
+          case lldb::eBasicTypeLongDouble:
+            if (type_width == constant_width) {
+              TypeSystemClang::SetFloatingInitializerForVariable(
+                  decl, basic_type_enum == lldb::eBasicTypeFloat
+                            ? llvm::APFloat(constant.Value.bitsToFloat())
+                            : llvm::APFloat(constant.Value.bitsToDouble()));
+            } else if (Log *log_ast = GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
+              LLDB_LOG(log_ast,
+                       "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
+                       "which resolves to a constant value of mismatched width "
+                       "({4} bits). Ignoring constant.",
+                       m_derived_ct.GetTypeName(), static_data_member.Name,
+                       member_ct.GetTypeName(), type_width, constant_width);
+            }
+            break;
+          default:
+            break;
+          }
+        }
+        break;
+      }
+    }
+  }
+
   // FIXME: Add a PdbSymUid namespace for field list members and update
   // the m_uid_to_decl map with this decl.
   return Error::success();
@@ -149,7 +213,7 @@
 
   TypeIndex ti(data_member.Type);
   if (!ti.isSimple()) {
-    CVType cvt = m_tpi.getType(ti);
+    CVType cvt = m_index.tpi().getType(ti);
     if (cvt.kind() == LF_BITFIELD) {
       BitFieldRecord bfr;
       llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr));
@@ -187,7 +251,7 @@
                                            OverloadedMethodRecord &overloaded) {
   TypeIndex method_list_idx = overloaded.MethodList;
 
-  CVType method_list_type = m_tpi.getType(method_list_idx);
+  CVType method_list_type = m_index.tpi().getType(method_list_idx);
   assert(method_list_type.kind() == LF_METHODLIST);
 
   MethodOverloadListRecord method_list;
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -681,7 +681,7 @@
   // Visit all members of this class, then perform any finalization necessary
   // to complete the class.
   CompilerType ct = ToCompilerType(tag_qt);
-  UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index.tpi());
+  UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index);
   auto error =
       llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer);
   completer.complete();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to