diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def b/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def index 86a74292dbb11..be0e81edbbb34 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def +++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def @@ -50,6 +50,7 @@ TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class) TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, Interface, Class) TYPE_RECORD(LF_UNION, 0x1506, Union) TYPE_RECORD(LF_ENUM, 0x1507, Enum) +TYPE_RECORD(LF_ALIAS, 0x150a, Alias) TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2) TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable) TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape) @@ -187,7 +188,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..1b937a8621f7a 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` - A typedef where `Name` is typedef'd to `UnderlyingType`. +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 2d1bfa6f8dcb9..bd02829c28cbe 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h @@ -428,6 +428,8 @@ class LVLogicalVisitor final { TypeIndex TI, LVElement *Element); LLVM_ABI Error visitKnownRecord(CVType &Record, EndPrecompRecord &EndPrecomp, TypeIndex TI, LVElement *Element); + LLVM_ABI Error visitKnownRecord(CVType &Record, AliasRecord &Alias, + TypeIndex TI, LVElement *Element); LLVM_ABI Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI); LLVM_ABI Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base, diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefAlias.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefAlias.h new file mode 100644 index 0000000000000..15203a91a6266 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefAlias.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFALIAS_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFALIAS_H + +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +namespace llvm { + +class raw_ostream; + +namespace pdb { + +class NativeSession; + +/// A typedef from the TPI stream (LF_ALIAS). +class LLVM_ABI NativeTypeTypedefAlias : public NativeRawSymbol { +public: + NativeTypeTypedefAlias(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, codeview::AliasRecord Typedef); + + NativeTypeTypedefAlias(NativeSession &Session, SymIndexId Id, + NativeTypeTypedefAlias &UnmodifiedType, + codeview::ModifierRecord Modifier); + + ~NativeTypeTypedefAlias() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + std::string getName() const override; + SymIndexId getTypeId() const override; + + SymIndexId getUnmodifiedTypeId() const override; + bool isConstType() const override; + bool isUnalignedType() const override; + bool isVolatileType() const override; + +protected: + codeview::AliasRecord Record; + NativeTypeTypedefAlias *UnmodifiedType = nullptr; + std::optional Modifiers; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFALIAS_H diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefUDT.h similarity index 64% rename from llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h rename to llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefUDT.h index b1201276284f5..5057204ed76e1 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefUDT.h @@ -1,4 +1,4 @@ -//===- NativeTypeTypedef.h - info about typedef ------------------*- C++-*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H -#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFUDT_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFUDT_H #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" @@ -22,13 +22,14 @@ namespace pdb { class NativeSession; -class LLVM_ABI NativeTypeTypedef : public NativeRawSymbol { +/// A typedef from the module symbol stream (S_UDT). +class LLVM_ABI NativeTypeTypedefUDT : public NativeRawSymbol { public: // Create a pointer record for a non-simple type. - NativeTypeTypedef(NativeSession &Session, SymIndexId Id, - codeview::UDTSym Typedef); + NativeTypeTypedefUDT(NativeSession &Session, SymIndexId Id, + codeview::UDTSym Typedef); - ~NativeTypeTypedef() override; + ~NativeTypeTypedefUDT() override; void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, PdbSymbolIdField RecurseIdFields) const override; @@ -43,4 +44,4 @@ class LLVM_ABI NativeTypeTypedef : public NativeRawSymbol { } // namespace pdb } // namespace llvm -#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFUDT_H diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/llvm/lib/DebugInfo/CodeView/RecordName.cpp index 476f9bb935379..32b2267c06b3b 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 7dd2bad7da2e1..00f309ce45446 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp @@ -439,3 +439,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/TypeIndexDiscovery.cpp b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp index c19e72187fc9c..38264aa12b3d6 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp @@ -352,6 +352,9 @@ static void discoverTypeIndices(ArrayRef Content, TypeLeafKind Kind, case TypeLeafKind::LF_POINTER: handlePointer(Content, Refs); break; + case TypeLeafKind::LF_ALIAS: + Refs.push_back({TiRefKind::TypeRef, 0, 1}); // UnderlyingType + break; default: break; } diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp index e8c9744935bf7..ea436e846e0ee 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp @@ -721,3 +721,9 @@ 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 7320a188051bb..5f6b0f513d37d 100644 --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp @@ -2671,6 +2671,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/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index afde28914dacd..e9fa6f8229bb1 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -69,7 +69,8 @@ add_pdb_impl_folder(Native Native/NativeTypeEnum.cpp Native/NativeTypeFunctionSig.cpp Native/NativeTypePointer.cpp - Native/NativeTypeTypedef.cpp + Native/NativeTypeTypedefAlias.cpp + Native/NativeTypeTypedefUDT.cpp Native/NativeTypeUDT.cpp Native/NativeTypeVTShape.cpp Native/NamedStreamMap.cpp diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp deleted file mode 100644 index 11cd349b72ca0..0000000000000 --- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h" -#include "llvm/DebugInfo/PDB/Native/NativeSession.h" -#include "llvm/DebugInfo/PDB/PDBExtras.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::pdb; - -NativeTypeTypedef::NativeTypeTypedef(NativeSession &Session, SymIndexId Id, - codeview::UDTSym Typedef) - : NativeRawSymbol(Session, PDB_SymType::Typedef, Id), - Record(std::move(Typedef)) {} - -NativeTypeTypedef::~NativeTypeTypedef() = default; - -void NativeTypeTypedef::dump(raw_ostream &OS, int Indent, - PdbSymbolIdField ShowIdFields, - PdbSymbolIdField RecurseIdFields) const { - NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); - dumpSymbolField(OS, "name", getName(), Indent); - dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, - PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); -} - -std::string NativeTypeTypedef::getName() const { - return std::string(Record.Name); -} - -SymIndexId NativeTypeTypedef::getTypeId() const { - return Session.getSymbolCache().findSymbolByTypeIndex(Record.Type); -} diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefAlias.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefAlias.cpp new file mode 100644 index 0000000000000..cb3119026f206 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefAlias.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedefAlias.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/PDBExtras.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +NativeTypeTypedefAlias::NativeTypeTypedefAlias(NativeSession &Session, + SymIndexId Id, + TypeIndex /* TI */, + codeview::AliasRecord Typedef) + : NativeRawSymbol(Session, PDB_SymType::Typedef, Id), + Record(std::move(Typedef)) {} + +NativeTypeTypedefAlias::NativeTypeTypedefAlias( + NativeSession &Session, SymIndexId Id, + NativeTypeTypedefAlias &UnmodifiedType, codeview::ModifierRecord Modifier) + : NativeRawSymbol(Session, PDB_SymType::Typedef, Id), + UnmodifiedType(&UnmodifiedType), Modifiers(Modifier) {} + +NativeTypeTypedefAlias::~NativeTypeTypedefAlias() = default; + +void NativeTypeTypedefAlias::dump(raw_ostream &OS, int Indent, + PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const { + NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); + dumpSymbolField(OS, "name", getName(), Indent); + dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, + PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); + dumpSymbolField(OS, "constType", isConstType(), Indent); + dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); + dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); +} + +std::string NativeTypeTypedefAlias::getName() const { + if (UnmodifiedType) + return UnmodifiedType->getName(); + return std::string(Record.Name); +} + +SymIndexId NativeTypeTypedefAlias::getTypeId() const { + if (UnmodifiedType) + return UnmodifiedType->getTypeId(); + + return Session.getSymbolCache().findSymbolByTypeIndex(Record.UnderlyingType); +} + +SymIndexId NativeTypeTypedefAlias::getUnmodifiedTypeId() const { + if (UnmodifiedType) + return UnmodifiedType->getSymIndexId(); + + return 0; +} + +bool NativeTypeTypedefAlias::isConstType() const { + if (!Modifiers) + return false; + return (Modifiers->Modifiers & ModifierOptions::Const) != + ModifierOptions::None; +} + +bool NativeTypeTypedefAlias::isUnalignedType() const { + if (!Modifiers) + return false; + return (Modifiers->Modifiers & ModifierOptions::Unaligned) != + ModifierOptions::None; +} + +bool NativeTypeTypedefAlias::isVolatileType() const { + if (!Modifiers) + return false; + return (Modifiers->Modifiers & ModifierOptions::Volatile) != + ModifierOptions::None; +} diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefUDT.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefUDT.cpp new file mode 100644 index 0000000000000..8404f4cc57a0d --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefUDT.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedefUDT.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/PDBExtras.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +NativeTypeTypedefUDT::NativeTypeTypedefUDT(NativeSession &Session, + SymIndexId Id, + codeview::UDTSym Typedef) + : NativeRawSymbol(Session, PDB_SymType::Typedef, Id), + Record(std::move(Typedef)) {} + +NativeTypeTypedefUDT::~NativeTypeTypedefUDT() = default; + +void NativeTypeTypedefUDT::dump(raw_ostream &OS, int Indent, + PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const { + NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); + dumpSymbolField(OS, "name", getName(), Indent); + dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, + PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); +} + +std::string NativeTypeTypedefUDT::getName() const { + return std::string(Record.Name); +} + +SymIndexId NativeTypeTypedefUDT::getTypeId() const { + return Session.getSymbolCache().findSymbolByTypeIndex(Record.Type); +} diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp index 4cb4472354267..d9de0f0b612bf 100644 --- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp @@ -28,7 +28,8 @@ #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h" -#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h" +#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedefAlias.h" +#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedefUDT.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" @@ -146,6 +147,10 @@ SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI, case PDB_SymType::UDT: return createSymbol( static_cast(UnmodifiedNRS), std::move(Record)); + case PDB_SymType::Typedef: + return createSymbol( + static_cast(UnmodifiedNRS), + std::move(Record)); default: // No other types can be modified. (LF_POINTER, for example, records // its modifiers a different way. @@ -232,6 +237,10 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) const { Id = createSymbolForType( Index, std::move(CVT)); break; + case codeview::LF_ALIAS: + Id = createSymbolForType( + Index, std::move(CVT)); + break; default: Id = createSymbolPlaceholder(); break; @@ -282,7 +291,7 @@ SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) { switch (CVS.kind()) { case SymbolKind::S_UDT: { UDTSym US = cantFail(SymbolDeserializer::deserializeAs(CVS)); - Id = createSymbol(std::move(US)); + Id = createSymbol(std::move(US)); break; } default: @@ -680,5 +689,3 @@ SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const { Iter->second = Id; return Id; } - - diff --git a/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp index 941ce78027a21..28967d55324c0 100644 --- a/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp @@ -85,6 +85,15 @@ static Expected getSourceLineHash(const CVType &Rec) { return hashStringV1(StringRef(Buf, 4)); } +// LF_ALIAS is considered a UDT, so only the name is hashed. +static Expected getHashForAlias(const CVType &Rec) { + AliasRecord Deserialized; + if (auto E = TypeDeserializer::deserializeAs(const_cast(Rec), + Deserialized)) + return std::move(E); + return hashStringV1(Deserialized.Name); +} + Expected llvm::pdb::hashTagRecord(const codeview::CVType &Type) { switch (Type.kind()) { case LF_CLASS: @@ -112,7 +121,8 @@ Expected llvm::pdb::hashTypeRecord(const CVType &Rec) { return getHashForUdt(Rec); case LF_ENUM: return getHashForUdt(Rec); - + case LF_ALIAS: + return getHashForAlias(Rec); case LF_UDT_SRC_LINE: return getSourceLineHash(Rec); case LF_UDT_MOD_SRC_LINE: diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp index 1542017d9d7e6..0470ec6f8056c 100644 --- a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp +++ b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -654,6 +654,11 @@ template <> void LeafRecordImpl::map(IO &IO) { IO.mapRequired("Signature", Record.Signature); } +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("UnderlyingType", Record.UnderlyingType); + IO.mapRequired("Name", Record.Name); +} + template <> void MemberRecordImpl::map(IO &IO) { MappingTraits::mapping(IO, Record); } diff --git a/llvm/test/DebugInfo/PDB/Native/pdb-native-typedefs-in-func.test b/llvm/test/DebugInfo/PDB/Native/pdb-native-typedefs-in-func.test new file mode 100644 index 0000000000000..cbc5040c7d511 --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Native/pdb-native-typedefs-in-func.test @@ -0,0 +1,92 @@ +# Test that the native PDB reader read typedefs from the TPI stream and modifiers on them. +# Note that DIA doesn't include LF_ALIAS when searching for typedefs. + +# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t.pdb +# RUN: llvm-pdbutil pretty -native -all %t.pdb \ +# RUN: | FileCheck -check-prefix=PRETTY %s + +# RUN: llvm-pdbutil diadump -native -funcsigs -recurse %t.pdb \ +# RUN: | FileCheck -check-prefix=DIADUMP %s + +# PRETTY: ---TYPES--- +# PRETTY-NEXT: Enums: (0 items) +# PRETTY-NEXT: Function Signatures: (1 items) +# PRETTY-NEXT: ALIAS __cdecl () +# PRETTY-NEXT: Typedefs: (0 items) +# PRETTY-NEXT: Pointers: (2 items) +# PRETTY-NEXT: typedef char16_t U16* +# PRETTY-NEXT: typedef char8_t MyByte* +# PRETTY-NEXT: Classes: (Showing 0 items) + +# DIADUMP: { +# DIADUMP-NEXT: symIndexId: 2 +# DIADUMP-NEXT: symTag: FunctionSig +# DIADUMP-NEXT: callingConvention: __cdecl +# DIADUMP-NEXT: count: 0 +# DIADUMP-NEXT: typeId: 3 +# DIADUMP-NEXT: symIndexId: 3 +# DIADUMP-NEXT: symTag: Typedef +# DIADUMP-NEXT: name: ALIAS +# DIADUMP-NEXT: typeId: 4 +# DIADUMP-NEXT: constType: 0 +# DIADUMP-NEXT: unalignedType: 0 +# DIADUMP-NEXT: volatileType: 0 +# DIADUMP-NEXT: constructor: 0 +# DIADUMP-NEXT: constType: 0 +# DIADUMP-NEXT: isConstructorVirtualBase: 0 +# DIADUMP-NEXT: isCxxReturnUdt: 0 +# DIADUMP-NEXT: unalignedType: 0 +# DIADUMP-NEXT: volatileType: 0 +# DIADUMP-NEXT: } + +--- +TpiStream: + Version: VC80 + Records: + - Kind: LF_ALIAS + Alias: + UnderlyingType: 116 + Name: ALIAS + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 4096 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4097 + - Kind: LF_ALIAS + Alias: + UnderlyingType: 122 + Name: U16 + - Kind: LF_MODIFIER + Modifier: + ModifiedType: 4099 + Modifiers: [ None, Const ] + - Kind: LF_POINTER + Pointer: + ReferentType: 4100 + Attrs: 65548 + - Kind: LF_ALIAS + Alias: + UnderlyingType: 124 + Name: MyByte + - Kind: LF_MODIFIER + Modifier: + ModifiedType: 4102 + Modifiers: [ None, Const ] + - Kind: LF_POINTER + Pointer: + ReferentType: 4103 + Attrs: 65548 +PublicsStream: + Records: + - Kind: S_PUB32 + PublicSym32: + Flags: [ Function ] + Offset: 0 + Segment: 1 + Name: main +... diff --git a/llvm/test/tools/llvm-pdbutil/alias-record.test b/llvm/test/tools/llvm-pdbutil/alias-record.test new file mode 100644 index 0000000000000..88a979ed5e659 --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/alias-record.test @@ -0,0 +1,45 @@ +# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t.pdb +# RUN: llvm-pdbutil dump --types --type-extras %t.pdb | FileCheck --check-prefix=CHECK-YAML2PDB %s + +# RUN: llvm-pdbutil pdb2yaml --tpi-stream %t.pdb > %t.yaml +# RUN: FileCheck --input-file=%t.yaml --check-prefix=CHECK-PDB2YAML %s + +# CHECK-YAML2PDB: 0x1000 | LF_ALIAS [size = 16, hash = 0x1876E] +# CHECK-YAML2PDB-NEXT: underlying type = 0x0070 (char), name = MyByte +# CHECK-YAML2PDB-NEXT: 0x1001 | LF_ALIAS [size = 12, hash = 0x1D4A] +# CHECK-YAML2PDB-NEXT: underlying type = 0x007A (char16_t), name = U16 +# CHECK-YAML2PDB-NEXT: 0x1002 | LF_ALIAS [size = 16, hash = 0x1876E] +# CHECK-YAML2PDB-NEXT: underlying type = 0x007A (char16_t), name = MyByte + +# CHECK-PDB2YAML: Records: +# CHECK-PDB2YAML-NEXT: - Kind: LF_ALIAS +# CHECK-PDB2YAML-NEXT: Alias: +# CHECK-PDB2YAML-NEXT: UnderlyingType: 112 +# CHECK-PDB2YAML-NEXT: Name: MyByte +# CHECK-PDB2YAML-NEXT: - Kind: LF_ALIAS +# CHECK-PDB2YAML-NEXT: Alias: +# CHECK-PDB2YAML-NEXT: UnderlyingType: 122 +# CHECK-PDB2YAML-NEXT: Name: U16 +# CHECK-PDB2YAML-NEXT: - Kind: LF_ALIAS +# CHECK-PDB2YAML-NEXT: Alias: +# CHECK-PDB2YAML-NEXT: UnderlyingType: 122 +# CHECK-PDB2YAML-NEXT: Name: MyByte +# CHECK-PDB2YAML-NEXT: ... + +--- +TpiStream: + Version: VC80 + Records: + - Kind: LF_ALIAS + Alias: + UnderlyingType: 112 + Name: MyByte + - Kind: LF_ALIAS + Alias: + UnderlyingType: 122 + Name: U16 + - Kind: LF_ALIAS + Alias: + UnderlyingType: 122 + Name: MyByte +... diff --git a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp index fc29ec46180c4..13677bce09b75 100644 --- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp +++ b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp @@ -535,6 +535,11 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, return Error::success(); } +Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, AliasRecord &AR) { + P.formatLine("underlying type = {0}, name = {1}", AR.UnderlyingType, AR.Name); + return Error::success(); +} + Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR, NestedTypeRecord &Nested) { P.format(" [name = `{0}`, parent = {1}]", Nested.Name, Nested.Type); diff --git a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp index 810aeada33da7..5f11de113c747 100644 --- a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp +++ b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp @@ -613,3 +613,9 @@ TEST_F(TypeIndexIteratorTest, RegRelativeIndir) { writeSymbolRecords(RR); checkTypeReferences(0, RR.Type); } + +TEST_F(TypeIndexIteratorTest, AliasRecord) { + AliasRecord AR(TypeIndex::Int32(), "SomeName"); + writeTypeRecords(AR); + checkTypeReferences(0, AR.UnderlyingType); +}