Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
13 changes: 13 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any change to getSizeInBytesForTypeRecord - I don't think the default case is correct though, should we be forwarding the size of the underlying type?

@Nerixyz Nerixyz Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the default case is correct though, should we be forwarding the size of the underlying type?

Yeah - it returns (essentially) garbage for non-aggregates, the comment above says that

/// Given an arbitrary codeview type, return the type's size in the case
/// of aggregate (LF_STRUCTURE, LF_CLASS, LF_INTERFACE, LF_UNION).

I don't see LF_ALIAS as an aggregate. And given the function signature, it shouldn't read in the TPI stream. In my opinion, it should return an optional and only return the size in the documented cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm that also seems wrong - it should handle modifiers too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #218715 for this.

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;
Comment thread
dpaoliello marked this conversation as resolved.
};

} // end namespace codeview
} // end namespace llvm

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
57 changes: 57 additions & 0 deletions llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedefAlias.h
Original file line number Diff line number Diff line change
@@ -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<codeview::ModifierRecord> Modifiers;
};

} // namespace pdb
} // namespace llvm

#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEFALIAS_H
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//===- 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.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#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"
Expand All @@ -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;
Expand All @@ -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
5 changes: 5 additions & 0 deletions llvm/lib/DebugInfo/CodeView/RecordName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
3 changes: 3 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ static void discoverTypeIndices(ArrayRef<uint8_t> 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;
}
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
12 changes: 12 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)); });
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/DebugInfo/PDB/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 0 additions & 31 deletions llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp

This file was deleted.

83 changes: 83 additions & 0 deletions llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefAlias.cpp
Original file line number Diff line number Diff line change
@@ -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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused - where does this Modifier come from? Why aren't we dumping it elsewhere?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like dead functionality, perhaps exercised by the original PR. I would leave it out of scope if you don't need it for the core parsing / dumping code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't dead - it's used in SymbolCache::createSymbolForModifiedType. It's similar to how modifiers for tag records are handled.

: 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;
}
40 changes: 40 additions & 0 deletions llvm/lib/DebugInfo/PDB/Native/NativeTypeTypedefUDT.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
Loading
Loading