llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-platform-windows

@llvm/pr-subscribers-debuginfo

Author: Walnut (Walnut356)

<details>
<summary>Changes</summary>

This patch causes LLVM to emit `lf_alias` nodes for typedefs, allowing typedefs 
to be represented in the type data stream. Typedef `S_UDT` nodes are still 
created for the symbol stream. This strictly generates additional information 
and points to that additional information when possible.

This is important because local variable symbols store *type* indexes. Without 
this change, it is impossible for a local variable to convey its typedefed type 
to the debugger.

&lt;details&gt;
&lt;summary&gt;Sample program&lt;/summary&gt;

```cpp
#include &lt;iostream&gt;
#include &lt;inttypes.h&gt;

struct Point {
  float x = 0.0;
  float y = 0.0;
};

typedef Point Coord;

int main() {
  unsigned char uc = 0;
  uint8_t u8 = 1;
  Point p = Point{5, 10};
  Coord c = Coord{15, 20};
  std::cout &lt;&lt; "Hello World!\n";
}
```
&lt;/details&gt;

Before (LLVM 20.1.8):

&lt;img width="261" height="191" alt="image" 
src="https://github.com/user-attachments/assets/cb9e9e7e-3ad0-4e3a-81c7-5edb4248d2db";
 /&gt;

After:

&lt;img width="221" height="179" alt="image" 
src="https://github.com/user-attachments/assets/d6035b33-ce5c-4b22-a6c0-aa38b2495fb3";
 /&gt;

Please use extra scrutiny when looking over the LLDB-related changes. I have a 
bit of experience working with `SymbolFileNativePDB` and `PdbAstBuilder`, but 
I'm not super familiar with clang's `QualType` and such. In particular, I'm 
using a default `CompilerDeclContext` for the typedef type because I wasn't 
sure what else to use. 

---
Full diff: https://github.com/llvm/llvm-project/pull/152484.diff


13 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (+14) 
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp 
(+15) 
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h 
(+3) 
- (modified) llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def (+1-1) 
- (modified) llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h (+13) 
- (modified) 
llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h (+2) 
- (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+4-9) 
- (modified) llvm/lib/DebugInfo/CodeView/RecordName.cpp (+5) 
- (modified) llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp (+6) 
- (modified) llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp (+7) 
- (modified) llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp (+12) 
- (modified) llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp (+5) 
- (modified) llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp (+7) 


``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp 
b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index f01fba3c48ce9..db29c96b6194a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -805,6 +805,20 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId 
type) {
     return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);
   }
 
+  if (cvt.kind() == LF_ALIAS) {
+    AliasRecord ar;
+    llvm::cantFail(TypeDeserializer::deserializeAs<AliasRecord>(cvt, ar));
+
+    auto underlying_type = ToCompilerType(GetOrCreateType(ar.UnderlyingType));
+
+    std::string name = std::string(DropNameScope(ar.Name));
+
+    CompilerType ct = underlying_type.CreateTypedef(
+        name.c_str(), CompilerDeclContext(), 0);
+
+    return m_clang.GetQualType(ct.GetOpaqueQualType());
+  }
+
   return {};
 }
 
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp 
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index dcea33dd9f854..57a4c29a037e6 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -709,6 +709,15 @@ TypeSP 
SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
                   ct, lldb_private::Type::ResolveState::Full);
 }
 
+TypeSP SymbolFileNativePDB::CreateAliasType(PdbTypeSymId type_id,
+                                            const AliasRecord &ar,
+                                            CompilerType ct) {
+
+  return MakeType(toOpaqueUid(type_id), ct.GetTypeName(), 
llvm::expectedToOptional(ct.GetByteSize(nullptr)), nullptr, LLDB_INVALID_UID,
+                  lldb_private::Type::eEncodingIsUID, Declaration(), ct,
+                  lldb_private::Type::ResolveState::Full);
+}
+
 TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
   if (type_id.index.isSimple())
     return CreateSimpleType(type_id.index, ct);
@@ -765,6 +774,12 @@ TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId 
type_id, CompilerType ct) {
     return CreateFunctionType(type_id, mfr, ct);
   }
 
+  if (cvt.kind() == LF_ALIAS) {
+    AliasRecord ar;
+    llvm::cantFail(TypeDeserializer::deserializeAs<AliasRecord>(cvt, ar));
+    return CreateAliasType(type_id, ar, ct);
+  }
+
   return nullptr;
 }
 
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h 
b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index eda375d4cebe7..1ed2f22293b43 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -216,6 +216,9 @@ class SymbolFileNativePDB : public SymbolFileCommon {
   lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id,
                                    const llvm::codeview::ProcedureRecord &pr,
                                    CompilerType ct);
+  lldb::TypeSP CreateAliasType(PdbTypeSymId type_id,
+                               const llvm::codeview::AliasRecord &ar,
+                               CompilerType ct);
   lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id,
                                       const llvm::codeview::TagRecord &record,
                                       size_t size, CompilerType ct);
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def 
b/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
index a31111eb80a4e..aa3beea75c75b 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
@@ -53,6 +53,7 @@ TYPE_RECORD(LF_ENUM, 0x1507, Enum)
 TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
 TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable)
 TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape)
+TYPE_RECORD(LF_ALIAS, 0x150a, Alias)
 
 TYPE_RECORD(LF_BITFIELD, 0x1205, BitField)
 
@@ -181,7 +182,6 @@ CV_TYPE(LF_MANAGED_ST, 0x140f)
 CV_TYPE(LF_ST_MAX, 0x1500)
 CV_TYPE(LF_TYPESERVER, 0x1501)
 CV_TYPE(LF_DIMARRAY, 0x1508)
-CV_TYPE(LF_ALIAS, 0x150a)
 CV_TYPE(LF_DEFARG, 0x150b)
 CV_TYPE(LF_FRIENDFCN, 0x150c)
 CV_TYPE(LF_NESTTYPEEX, 0x1512)
diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h 
b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
index 5a84fac5f5903..0e739650bd089 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
@@ -952,6 +952,19 @@ class EndPrecompRecord : public TypeRecord {
   uint32_t Signature = 0;
 };
 
+// LF_ALIAS
+class AliasRecord : public TypeRecord {
+public:
+  AliasRecord() = default;
+  explicit AliasRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
+  AliasRecord(TypeIndex UnderlyingType, StringRef Name)
+      : TypeRecord(TypeRecordKind::Alias), UnderlyingType(UnderlyingType), 
Name(Name) {}
+
+  TypeIndex UnderlyingType;
+  StringRef Name;
+
+};
+
 } // end namespace codeview
 } // end namespace llvm
 
diff --git 
a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h 
b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
index eb6371e911be4..164ea990336e0 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
@@ -418,6 +418,8 @@ class LVLogicalVisitor final {
                          LVElement *Element);
   Error visitKnownRecord(CVType &Record, EndPrecompRecord &EndPrecomp,
                          TypeIndex TI, LVElement *Element);
+  Error visitKnownRecord(CVType &Record, AliasRecord &Alias,
+                         TypeIndex TI, LVElement *Element);
 
   Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI);
   Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base,
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index c5d6e40eb7c1e..29978c9e5270f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1728,6 +1728,9 @@ TypeIndex CodeViewDebug::lowerTypeAlias(const 
DIDerivedType *Ty) {
 
   addToUDTs(Ty);
 
+  AliasRecord AR(UnderlyingTypeIndex, TypeName);
+  auto alias_index = TypeTable.writeLeafType(AR);
+
   if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) &&
       TypeName == "HRESULT")
     return TypeIndex(SimpleTypeKind::HResult);
@@ -1735,7 +1738,7 @@ TypeIndex CodeViewDebug::lowerTypeAlias(const 
DIDerivedType *Ty) {
       TypeName == "wchar_t")
     return TypeIndex(SimpleTypeKind::WideCharacter);
 
-  return UnderlyingTypeIndex;
+  return alias_index;
 }
 
 TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
@@ -2750,14 +2753,6 @@ TypeIndex CodeViewDebug::getCompleteTypeIndex(const 
DIType *Ty) {
   if (!Ty)
     return TypeIndex::Void();
 
-  // Look through typedefs when getting the complete type index. Call
-  // getTypeIndex on the typdef to ensure that any UDTs are accumulated and are
-  // emitted only once.
-  if (Ty->getTag() == dwarf::DW_TAG_typedef)
-    (void)getTypeIndex(Ty);
-  while (Ty->getTag() == dwarf::DW_TAG_typedef)
-    Ty = cast<DIDerivedType>(Ty)->getBaseType();
-
   // If this is a non-record type, the complete type index is the same as the
   // normal type index. Just call getTypeIndex.
   switch (Ty->getTag()) {
diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp 
b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index e06b036ede63a..80c9cfa2253fb 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -251,6 +251,11 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR,
   return Error::success();
 }
 
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, AliasRecord &Alias) {
+  Name = Alias.Name;
+  return Error::success();
+}
+
 std::string llvm::codeview::computeTypeName(TypeCollection &Types,
                                             TypeIndex Index) {
   TypeNameComputer Computer(Types);
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp 
b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index 776676410e782..629b7e5746ff4 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
@@ -568,3 +568,9 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
   W->printHex("Signature", EndPrecomp.getSignature());
   return Error::success();
 }
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, AliasRecord &Alias) {
+  printTypeIndex("UnderlyingType", Alias.UnderlyingType);
+  W->printString("Name", Alias.Name);
+  return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp 
b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index 0bc65f8d0359a..530a119de85fe 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -752,3 +752,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
   error(IO.mapInteger(EndPrecomp.Signature, "Signature"));
   return Error::success();
 }
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, AliasRecord &Alias) {
+  error(IO.mapInteger(Alias.UnderlyingType, "UnderlyingType"));
+  error(IO.mapStringZ(Alias.Name, "Name"));
+
+  return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp 
b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index 24eaa1234727d..6cd53d42a43cd 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -2623,6 +2623,18 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
   return Error::success();
 }
 
+// LF_ALIAS (TPI)
+Error LVLogicalVisitor::visitKnownRecord(CVType &Record, AliasRecord &Alias,
+                                         TypeIndex TI, LVElement *Element) {
+  LLVM_DEBUG({
+    printTypeBegin(Record, TI, Element, StreamTPI);
+    printTypeIndex("UnderlyingType", Alias.UnderlyingType, StreamTPI);
+    W.printString("Name", Alias.Name);
+    printTypeEnd(Record);
+  });
+  return Error::success();
+}
+
 Error LVLogicalVisitor::visitUnknownMember(CVMemberRecord &Record,
                                            TypeIndex TI) {
   LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp 
b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
index f4ca1b22eafa0..84f33a3fea6a8 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
@@ -614,6 +614,11 @@ template <> void LeafRecordImpl<EndPrecompRecord>::map(IO 
&IO) {
   IO.mapRequired("Signature", Record.Signature);
 }
 
+template <> void LeafRecordImpl<AliasRecord>::map(IO &IO) {
+  IO.mapRequired("UnderlyingType", Record.UnderlyingType);
+  IO.mapRequired("Name", Record.Name);
+}
+
 template <> void MemberRecordImpl<OneMethodRecord>::map(IO &IO) {
   MappingTraits<OneMethodRecord>::mapping(IO, Record);
 }
diff --git a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp 
b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
index db3a752d58165..7931d606a7bf8 100644
--- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
@@ -523,6 +523,13 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
   return Error::success();
 }
 
+Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVT,
+                                               AliasRecord &Alias) {
+  P.format("alias = {0}, underlying type = {1}", Alias.Name,
+           Alias.UnderlyingType);
+  return Error::success();
+}
+
 Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                                NestedTypeRecord &Nested) {
   P.format(" [name = `{0}`, parent = {1}]", Nested.Name, Nested.Type);

``````````

</details>


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

Reply via email to