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 @@ -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)

Expand Down Expand Up @@ -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)
Expand Down
12 changes: 12 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,18 @@ 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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 4 additions & 9 deletions llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1728,14 +1728,17 @@ TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) {

addToUDTs(Ty);

AliasRecord AR(UnderlyingTypeIndex, TypeName);
auto AliasIndex = TypeTable.writeLeafType(AR);

if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) &&
TypeName == "HRESULT")
return TypeIndex(SimpleTypeKind::HResult);
if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::UInt16Short) &&
TypeName == "wchar_t")
return TypeIndex(SimpleTypeKind::WideCharacter);

return UnderlyingTypeIndex;
return AliasIndex;
}

TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
Expand Down Expand Up @@ -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()) {
Expand Down
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 @@ -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();
}
7 changes: 7 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
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 @@ -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)); });
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,11 @@ template <> void LeafRecordImpl<EndPrecompRecord>::map(IO &IO) {
IO.mapRequired("Signature", Record.Signature);
}

template <> void LeafRecordImpl<AliasRecord>::map(IO &IO) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we test this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe so, I would dig around in the yaml tests for an example to add to.

IO.mapRequired("UnderlyingType", Record.UnderlyingType);
IO.mapRequired("Name", Record.Name);
}

template <> void MemberRecordImpl<OneMethodRecord>::map(IO &IO) {
MappingTraits<OneMethodRecord>::mapping(IO, Record);
}
Expand Down
43 changes: 43 additions & 0 deletions llvm/test/DebugInfo/PDB/Inputs/typedef.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
; ModuleID = 'typedef.cpp'
source_filename = "typedef.cpp"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc19.44.35214"

; Function Attrs: mustprogress noinline norecurse nounwind optnone uwtable
define dso_local noundef i32 @main() #0 !dbg !14 {
entry:
%retval = alloca i32, align 4
%val = alloca i8, align 1
%val2 = alloca i64, align 8
store i32 0, ptr %retval, align 4
#dbg_declare(ptr %val, !19, !DIExpression(), !22)
store i8 15, ptr %val, align 1, !dbg !22
#dbg_declare(ptr %val2, !23, !DIExpression(), !26)
store i64 -1, ptr %val2, align 8, !dbg !26
ret i32 0, !dbg !27
}

attributes #0 = { mustprogress noinline norecurse nounwind optnone uwtable }

!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!13}

!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !5, producer: "clang version 22.0.0git (https://github.com/Walnut356/llvm-project.git 0e257f7d7edfcda5655eeaac55d0ffc398e773a2)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!5 = !DIFile(filename: "typedef.cpp", directory: "llvm-project")
!7 = !{i32 2, !"CodeView", i32 1}
!8 = !{i32 2, !"Debug Info Version", i32 3}
!13 = !{!"clang version 22.0.0git (https://github.com/Walnut356/llvm-project.git 0e257f7d7edfcda5655eeaac55d0ffc398e773a2)"}
!14 = distinct !DISubprogram(name: "main", scope: !5, file: !5, line: 6, type: !15, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2)
!15 = !DISubroutineType(types: !16)
!16 = !{!17}
!17 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!19 = !DILocalVariable(name: "val", scope: !14, file: !5, line: 7, type: !20)
!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "u8", file: !5, line: 3, baseType: !21)
!21 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char)
!22 = !DILocation(line: 7, scope: !14)
!23 = !DILocalVariable(name: "val2", scope: !14, file: !5, line: 8, type: !24)
!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "i64", file: !5, line: 4, baseType: !25)
!25 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed)
!26 = !DILocation(line: 8, scope: !14)
!27 = !DILocation(line: 10, scope: !14)
12 changes: 12 additions & 0 deletions llvm/test/DebugInfo/PDB/Inputs/typedef.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
TpiStream:
Records:
- Kind: LF_ALIAS
Alias:
UnderlyingType: 32
Name: u8
- Kind: LF_ALIAS
Alias:
UnderlyingType: 19
Name: i64
...
62 changes: 62 additions & 0 deletions llvm/test/DebugInfo/PDB/typedef.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Built with clang (22+) because MSVC does not output lf_alias for typedefs

Build typedef.ll with clang -S -emit-llvm -g:

```
void *__purecall = 0;

typedef unsigned char u8;
using i64 = long long;

int main() {
u8 val = 15;
i64 val2 = -1;

return 0;
}
```

RUN: llc -O0 %p/Inputs/typedef.ll --filetype=obj -o %t.obj
RUN: llvm-pdbutil dump --types %t.obj | FileCheck --check-prefix=OBJTYPE %s

OBJTYPE: 0x1003 | LF_ALIAS [size = 12] alias = u8, underlying type = 0x0020 (unsigned char)
OBJTYPE-NEXT: 0x1004 | LF_ALIAS [size = 12] alias = i64, underlying type = 0x0013 (__int64)

RUN: llvm-pdbutil dump --symbols %t.obj | FileCheck --check-prefix=OBJSYM %s

OBJSYM: 0 | S_LOCAL [size = 16] `val`
OBJSYM-NEXT: type=0x1003 (u8), flags = none
OBJSYM: 0 | S_LOCAL [size = 16] `val2`
OBJSYM: type=0x1004 (i64), flags = none
OBJSYM: 0 | S_UDT [size = 12] `u8`
OBJSYM-NEXT: original type = 0x1003
OBJSYM-NEXT: 0 | S_UDT [size = 12] `i64`
OBJSYM-NEXT: original type = 0x1004


typedef.yaml file generated via `clang -fno-rtti -g -O0 typedef.cpp` and `llvm-pdbutil pdb2yaml -tpi-stream`, and then manually
reduced to only the typedef nodes

RUN: llvm-pdbutil yaml2pdb -pdb=%t.yaml.pdb %p/Inputs/typedef.yaml
RUN: llvm-pdbutil dump --types %t.yaml.pdb \
RUN: | FileCheck --check-prefix=TYPES %s

Also check that the YAML output hasn't drifted
RUN: llvm-pdbutil pdb2yaml -tpi-stream %t.yaml.pdb \
RUN: | FileCheck --check-prefixes=YAML %s

TYPES: Types (TPI Stream)
TYPES-NEXT:============================================================
TYPES-NEXT: Showing 2 records
TYPES-NEXT: 0x1000 | LF_ALIAS [size = 12] alias = u8, underlying type = 0x0020 (unsigned char)
TYPES-NEXT: 0x1001 | LF_ALIAS [size = 12] alias = i64, underlying type = 0x0013 (__int64)


YAML: - Kind: LF_ALIAS
YAML-NEXT: Alias:
YAML-NEXT: UnderlyingType: 32
YAML-NEXT: Name: u8
YAML-NEXT: - Kind: LF_ALIAS
YAML-NEXT: Alias:
YAML-NEXT: UnderlyingType: 19
YAML-NEXT: Name: i64
7 changes: 7 additions & 0 deletions llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down