Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -17,6 +17,7 @@ #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" @@ -460,7 +461,78 @@ S.OpeningRecord->PtrEnd = CurOffset; } +static bool symbolGoesInModuleStream(const CVSymbol &Sym) { + switch (Sym.kind()) { + case SymbolKind::S_GDATA32: + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + // We really should not be seeing S_PROCREF and S_LPROCREF in the first place + // since they are synthesized by the linker in response to S_GPROC32 and + // S_LPROC32, but if we do see them, don't put them in the module stream I + // guess. + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: + return false; + // S_GDATA32 does not go in the module stream, but S_LDATA32 does. + case SymbolKind::S_LDATA32: + default: + return true; + } +} + +static bool symbolGoesInGlobalsStream(const CVSymbol &Sym) { + switch (Sym.kind()) { + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + case SymbolKind::S_GDATA32: + // S_LDATA32 goes in both the module stream and the globals stream. + case SymbolKind::S_LDATA32: + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + // We really should not be seeing S_PROCREF and S_LPROCREF in the first place + // since they are synthesized by the linker in response to S_GPROC32 and + // S_LPROC32, but if we do see them, copy them straight through. + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: + return true; + default: + return false; + } +} + +static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, ObjFile &File, + const CVSymbol &Sym) { + switch (Sym.kind()) { + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: + Builder.addGlobalSymbol(Sym); + break; + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: { + SymbolRecordKind K = SymbolRecordKind::ProcRefSym; + if (Sym.kind() == SymbolKind::S_LPROC32) + K = SymbolRecordKind::LocalProcRef; + ProcRefSym PS(K); + PS.Module = static_cast(File.ModuleDBI->getModuleIndex()); + // For some reason, MSVC seems to add one to this value. + ++PS.Module; + PS.Name = getSymbolName(Sym); + PS.SumName = 0; + PS.SymOffset = File.ModuleDBI->getNextSymbolOffset(); + Builder.addGlobalSymbol(PS); + break; + } + default: + llvm_unreachable("Invalid symbol kind!"); + } +} + static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File, + pdb::GSIStreamBuilder &GsiBuilder, const CVIndexMap &IndexMap, const TypeTableBuilder &IDTable, BinaryStreamRef SymData) { @@ -500,8 +572,15 @@ else if (symbolEndsScope(NewKind)) scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File); + // Add the symbol to the globals stream if necessary. Do this before adding + // the symbol to the module since we may need to get the next symbol offset, + // and writing to the module's symbol stream will update that offset. + if (symbolGoesInGlobalsStream(NewSym)) + addGlobalSymbol(GsiBuilder, *File, NewSym); + // Add the symbol to the module. - File->ModuleDBI->addSymbol(NewSym); + if (symbolGoesInModuleStream(NewSym)) + File->ModuleDBI->addSymbol(NewSym); } } @@ -567,7 +646,8 @@ File->ModuleDBI->addDebugSubsection(SS); break; case DebugSubsectionKind::Symbols: - mergeSymbolRecords(Alloc, File, IndexMap, IDTable, SS.getRecordData()); + mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, + IDTable, SS.getRecordData()); break; default: // FIXME: Process the rest of the subsections. @@ -626,9 +706,10 @@ // Construct IPI stream contents. addTypeInfo(Builder.getIpiBuilder(), IDTable); - // Compute the public symbols. + // Compute the public and global symbols. + auto &GsiBuilder = Builder.getGsiBuilder(); std::vector Publics; - Symtab->forEachSymbol([&Publics](Symbol *S) { + Symtab->forEachSymbol([&Publics, &GsiBuilder](Symbol *S) { // Only emit defined, live symbols that have a chunk. auto *Def = dyn_cast(S->body()); if (Def && Def->isLive() && Def->getChunk()) @@ -641,7 +722,6 @@ [](const PublicSym32 &L, const PublicSym32 &R) { return L.Name < R.Name; }); - auto &GsiBuilder = Builder.getGsiBuilder(); for (const PublicSym32 &Pub : Publics) GsiBuilder.addPublicSymbol(Pub); } Index: lld/trunk/test/COFF/Inputs/pdb-globals.yaml =================================================================== --- lld/trunk/test/COFF/Inputs/pdb-globals.yaml +++ lld/trunk/test/COFF/Inputs/pdb-globals.yaml @@ -0,0 +1,593 @@ +# // YAML Generated from the following source code: +# // Compile with clang-cl /Z7 /GS- /c t.obj pdb-globals.cpp +# +# void *__purecall = 0; +# +# struct HelloPoint { +# int X = 3; +# int Y = 4; +# int Z = 5; +# }; +# +# // S_LPROCREF +# static int LocalFunc() { return 42; } +# +# // S_PROCREF +# int GlobalFunc() { return 43; } +# +# // S_LDATA32 +# const int ConstantVar = 17; +# +# // S_GDATA32 +# const int *GlobalVar = &ConstantVar; +# +# // S_CONSTANT +# constexpr int ConstexprVar = 18; +# +# // S_UDT +# typedef HelloPoint HelloPointTypedef; +# +# int main(int argc, char **argv) { +# HelloPointTypedef P; +# int N = P.X + P.Y + P.Z; +# N += LocalFunc() + GlobalFunc(); +# N += *GlobalVar; +# N += ConstexprVar; +# } + + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E5B82B0000005DC3660F1F4400005589E583EC208B450C8B4D088D55F4894DEC89D18945E8E8000000008B4DF4034DF8034DFC894DF08945E4E8000000008945E0E80000000031C98B55E001C20355F08955F0A1000000008B000345F08945F08B45F083C0128945F089C883C4205DC366666666662E0F1F8400000000005589E5B82A0000005DC3 + Relocations: + - VirtualAddress: 40 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 60 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 68 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 86 + SymbolName: '?GlobalVar@@3PBHB' + Type: IMAGE_REL_I386_DIR32 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '00000000' + Relocations: + - VirtualAddress: 0 + SymbolName: _ConstantVar + Type: IMAGE_REL_I386_DIR32 + - Name: .bss + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E550894DFC8B4DFCC70103000000C7410404000000C741080500000089C883C4045DC3 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '11000000' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F100000036000000300047110000000000000000000000000A00000000000000000000000210000000000000000000476C6F62616C46756E630002004F110000F20000002000000000000000000000000A0000000000000001000000140000000000000010000000F1000000B60000002A00471100000000000000000000000062000000000000000000000006100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001F000000000053000D003E11031000000100617267760012004511160000000C0000001F000000000053000A003E1107100000000050001200451116000000F4FFFFFF1F000000000053000A003E117400000000004E001200451116000000F0FFFFFF1F0000000000530002004F110000F200000050000000000000000000000062000000000000000700000044000000000000001E0000000F0000001F0000001C000000200000002800000021000000450000002200000052000000230000005B00000024000000F1000000350000002F0046110000000000000000000000000A00000000000000000000000F100000000000000000004C6F63616C46756E630002004F11000000F20000002000000000000000000000000A000000000000000100000014000000000000000D000000F10000004B00000017000D11030400000000000000005F5F7075726563616C6C0016000D1111100000000000000000476C6F62616C5661720018000C1110100000000000000000436F6E7374616E745661720000F10000002D000000180008110710000048656C6C6F506F696E745479706564656600110008110910000048656C6C6F506F696E7400000000F4000000080000000100000000000000F30000003800000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E6370700000 + Subsections: + - !Symbols + Records: + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ ] + Machine: Pentium3 + FrontendMajor: 6 + FrontendMinor: 0 + FrontendBuild: 0 + FrontendQFE: 0 + BackendMajor: 6000 + BackendMinor: 0 + BackendBuild: 0 + BackendQFE: 0 + Version: 'clang version 6.0.0 ' + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 10 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4098 + Flags: [ ] + DisplayName: GlobalFunc + - Kind: S_PROC_ID_END + ScopeEndSym: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 98 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4102 + Flags: [ ] + DisplayName: main + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: argc + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 4099 + Flags: [ IsParameter ] + VarName: argv + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 4103 + Flags: [ ] + VarName: P + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ ] + VarName: N + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + - Kind: S_LPROC32_ID + ProcSym: + CodeSize: 10 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4111 + Flags: [ ] + DisplayName: LocalFunc + - Kind: S_PROC_ID_END + ScopeEndSym: + - Kind: S_GDATA32 + DataSym: + Type: 1027 + DisplayName: __purecall + - Kind: S_GDATA32 + DataSym: + Type: 4113 + DisplayName: GlobalVar + - Kind: S_LDATA32 + DataSym: + Type: 4112 + DisplayName: ConstantVar + - Kind: S_UDT + UDTSym: + Type: 4103 + UDTName: HelloPointTypedef + - Kind: S_UDT + UDTSym: + Type: 4105 + UDTName: HelloPoint + - !FileChecksums + Checksums: + - FileName: 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' + Kind: None + Checksum: '' + - !StringTable + Strings: + - 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' + - '' + Relocations: + - VirtualAddress: 100 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 104 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 132 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 136 + SymbolName: '?GlobalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 204 + SymbolName: _main + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 208 + SymbolName: _main + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 243 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 247 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 278 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 282 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 310 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 314 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 342 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 346 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 364 + SymbolName: _main + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 368 + SymbolName: _main + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 484 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 488 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 516 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 520 + SymbolName: '?LocalFunc@@YAHXZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 564 + SymbolName: '?__purecall@@3PAXA' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 568 + SymbolName: '?__purecall@@3PAXA' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 589 + SymbolName: '?GlobalVar@@3PBHB' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 593 + SymbolName: '?GlobalVar@@3PBHB' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 613 + SymbolName: _ConstantVar + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 617 + SymbolName: _ConstantVar + Type: IMAGE_REL_I386_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 0400000006000112000000000E000810740000000000000000100000160001160000000001100000476C6F62616C46756E6300F10A000210700400000A8000000E0001120200000074000000031000000E0008107400000000000200041000001200011600000000051000006D61696E00F3F2F13200051500008002000000000000000000000000000048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F1260003120D15030074000000000058000D15030074000000040059000D1503007400000008005A0032000515030000020810000000000000000000000C0048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F13E00051600000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E63707000F2F10E000616091000000A100000060000000A000210071000000A8000001A00091003000000071000000C1000000B000000001000000000000016000216071000000D10000048656C6C6F506F696E7400F11600011600000000011000004C6F63616C46756E6300F2F10A000110740000000100F2F10A000210101000000A800000 + Types: + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4096 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4097 + Name: GlobalFunc + - Kind: LF_POINTER + Pointer: + ReferentType: 1136 + Attrs: 32778 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 116, 4099 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 2 + ArgumentList: 4100 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4101 + Name: main + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: HelloPoint + UniqueName: '.?AUHelloPoint@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 0 + Name: X + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 4 + Name: Y + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 8 + Name: Z + - Kind: LF_STRUCTURE + Class: + MemberCount: 3 + Options: [ None, HasUniqueName ] + FieldList: 4104 + Name: HelloPoint + UniqueName: '.?AUHelloPoint@@' + DerivationList: 0 + VTableShape: 0 + Size: 12 + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'd:\src\llvm-mono\lld\test\coff\inputs\pdb-globals.cpp' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4105 + SourceFile: 4106 + LineNumber: 6 + - Kind: LF_POINTER + Pointer: + ReferentType: 4103 + Attrs: 32778 + - Kind: LF_MFUNCTION + MemberFunction: + ReturnType: 3 + ClassType: 4103 + ThisType: 4108 + CallConv: ThisCall + Options: [ None ] + ParameterCount: 0 + ArgumentList: 4096 + ThisPointerAdjustment: 0 + - Kind: LF_MFUNC_ID + MemberFuncId: + ClassType: 4103 + FunctionType: 4109 + Name: HelloPoint + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4097 + Name: LocalFunc + - Kind: LF_MODIFIER + Modifier: + ModifiedType: 116 + Modifiers: [ None, Const ] + - Kind: LF_POINTER + Pointer: + ReferentType: 4112 + Attrs: 32778 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F1000000650000003C0047110000000000000000000000002500000000000000000000000E1000000000000000000048656C6C6F506F696E743A3A48656C6C6F506F696E74000D003E110C100000010074686973001200451116000000FCFFFFFF0A00000000001B0002004F11000000F20000004000000000000000000000002500000000000000050000003400000000000000060000000A00000007000000100000000800000017000000090000001E00000006000000 + Subsections: + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 37 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4110 + Flags: [ ] + DisplayName: 'HelloPoint::HelloPoint' + - Kind: S_LOCAL + LocalSym: + Type: 4108 + Flags: [ IsParameter ] + VarName: this + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + Relocations: + - VirtualAddress: 44 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 48 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 101 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 105 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 124 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 128 + SymbolName: '??0HelloPoint@@QAE@XZ' + Type: IMAGE_REL_I386_SECTION +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 138 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 3215092891 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 2 + - Name: .bss + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: .text + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 37 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 77530982 + Number: 4 + Selection: IMAGE_COMDAT_SELECT_ANY + - Name: '??0HelloPoint@@QAE@XZ' + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .rdata + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 4 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3903140090 + Number: 5 + - Name: .drectve + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 6 + - Name: '.debug$S' + Value: 0 + SectionNumber: 7 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 768 + NumberOfRelocations: 26 + NumberOfLinenumbers: 0 + CheckSum: 2940884584 + Number: 7 + - Name: '.debug$S' + Value: 0 + SectionNumber: 9 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 188 + NumberOfRelocations: 6 + NumberOfLinenumbers: 0 + CheckSum: 1246640575 + Number: 4 + Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE + - Name: '.debug$T' + Value: 0 + SectionNumber: 8 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 452 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2561906059 + Number: 8 + - Name: '@feat.00' + Value: 1 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '?GlobalFunc@@YAHXZ' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _main + Value: 16 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '?LocalFunc@@YAHXZ' + Value: 128 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '?GlobalVar@@3PBHB' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '?__purecall@@3PAXA' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _ConstantVar + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... Index: lld/trunk/test/COFF/pdb-comdat.test =================================================================== --- lld/trunk/test/COFF/pdb-comdat.test +++ lld/trunk/test/COFF/pdb-comdat.test @@ -26,7 +26,7 @@ RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main -RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s +RUN: llvm-pdbutil dump -l -symbols -globals t.pdb | FileCheck %s CHECK: Lines CHECK: ============================================================ @@ -38,6 +38,20 @@ CHECK-NOT: c:\src\llvm-project\build\foo.h CHECK-LABEL: Mod 0002 | `* Linker *`: +CHECK-LABEL: Global Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Records +CHECK-NEXT: 84 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 120 +CHECK-NEXT: 128 | S_PROCREF [size = 20] `foo` +CHECK-NEXT: module = 1, sum name = 0, offset = 208 +CHECK-NEXT: 148 | S_PROCREF [size = 20] `bar` +CHECK-NEXT: module = 2, sum name = 0, offset = 120 +CHECK-NEXT: 104 | S_GDATA32 [size = 24] `global` +CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 +CHECK-NEXT: 168 | S_GDATA32 [size = 24] `global` +CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 + CHECK: Symbols CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`: @@ -54,17 +68,15 @@ CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = has async eh | opt speed CHECK: 196 | S_END [size = 4] -CHECK: 200 | S_GDATA32 [size = 24] `global` -CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100A` -CHECK: 232 | S_GPROC32 [size = 44] `foo` -CHECK: parent = 0, end = 308, addr = 0002:0032, code size = 15 +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100A` +CHECK: 208 | S_GPROC32 [size = 44] `foo` +CHECK: parent = 0, end = 284, addr = 0002:0032, code size = 15 CHECK: debug start = 0, debug end = 14, flags = none -CHECK: 276 | S_FRAMEPROC [size = 32] +CHECK: 252 | S_FRAMEPROC [size = 32] CHECK: size = 0, padding size = 0, offset to padding = 0 CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = marked inline | has async eh | opt speed -CHECK: 308 | S_END [size = 4] +CHECK: 284 | S_END [size = 4] CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`: CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj` CHECK: 60 | S_COMPILE3 [size = 60] @@ -79,9 +91,7 @@ CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 CHECK: flags = has async eh | opt speed CHECK: 196 | S_END [size = 4] -CHECK: 200 | S_GDATA32 [size = 24] `global` -CHECK: type = 0x0074 (int), addr = 0000:0000 -CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100D` +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100D` CHECK-NOT: S_GPROC32 {{.*}} `foo` CHECK-LABEL: Mod 0002 | `* Linker *`: Index: lld/trunk/test/COFF/pdb-global-gc.yaml =================================================================== --- lld/trunk/test/COFF/pdb-global-gc.yaml +++ lld/trunk/test/COFF/pdb-global-gc.yaml @@ -2,7 +2,7 @@ # RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj # RUN: lld-link %t.obj %t2.obj -debug -entry:main \ # RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -verbose -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s # This tests the case where an __imp_ chunk is discarded by linker GC. The debug # info may refer to the __imp_ symbol still. @@ -12,13 +12,17 @@ # int discarded() { return __wc_mb_cur; } # int main() { return g2; } -# CHECK: Symbols -# CHECK: ============================================================ -# CHECK: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: -# CHECK: 4 | S_GDATA32 [size = 28] `__wc_mb_cur` -# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 -# CHECK: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: -# CHECK: Mod 0002 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 28] `__wc_mb_cur` +# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 + +# CHECK: Symbols +# CHECK: ============================================================ +# CHECK-NEXT: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`: +# CHECK-NEXT: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`: +# CHECK-NEXT: Mod 0002 | `* Linker *`: --- !COFF header: Index: lld/trunk/test/COFF/pdb-globals.test =================================================================== --- lld/trunk/test/COFF/pdb-globals.test +++ lld/trunk/test/COFF/pdb-globals.test @@ -0,0 +1,46 @@ +RUN: yaml2obj %S/Inputs/pdb-globals.yaml > %t.obj +RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj +RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s + +# Test that we correctly distribute symbols between the globals and module +# symbol streams. Specifically: +# * S_UDT, S_GDATA32, and S_CONSTANT end up in the globals stream, and are +# omitted from the module stream. +# * S_GPROC32 and S_LPROC32 end up in the symbols stream, but S_PROCREF and +# S_LPROCREF are added to the globals stream that refer to the module +# stream. +# * S_LDATA32 is copied byte for byte into both streams. + + +CHECK-LABEL: Global Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Records +CHECK-NEXT: 340 | S_UDT [size = 20] `HelloPoint` +CHECK-NEXT: original type = 0x1007 +CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc` +CHECK-NEXT: module = 1, sum name = 0, offset = 52 +CHECK-NEXT: 188 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 108 +CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc` +CHECK-NEXT: module = 1, sum name = 0, offset = 292 +CHECK-NEXT: 360 | S_PROCREF [size = 40] `HelloPoint::HelloPoint` +CHECK-NEXT: module = 1, sum name = 0, offset = 376 +CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall` +CHECK-NEXT: type = 0x0403 (void*), addr = 0000:0000 +CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar` +CHECK-NEXT: type = 0x100B (const int*), addr = 0001:0000 +CHECK-NEXT: 312 | S_UDT [size = 28] `HelloPointTypedef` +CHECK-NEXT: original type = 0x1005 +CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar` +CHECK-NEXT: type = 0x100A (const int), addr = 0002:0000 + +CHECK-LABEL: Symbols +CHECK-NEXT: ============================================================ +CHECK-NEXT: Mod 0000 +CHECK-NOT: | S_GDATA32 +CHECK-NOT: | S_UDT +CHECK: 52 | S_GPROC32 [size = 52] `GlobalFunc` +CHECK: 108 | S_GPROC32 [size = 44] `main` +CHECK: 292 | S_LPROC32 [size = 52] `LocalFunc` +CHECK: 348 | S_LDATA32 [size = 28] `ConstantVar` +CHECK: 376 | S_GPROC32 [size = 64] `HelloPoint::HelloPoint` Index: lld/trunk/test/COFF/pdb-import-gc.yaml =================================================================== --- lld/trunk/test/COFF/pdb-import-gc.yaml +++ lld/trunk/test/COFF/pdb-import-gc.yaml @@ -1,7 +1,7 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link %t.obj %S/Inputs/pdb-import-gc.lib -debug -entry:main \ # RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -# RUN: llvm-pdbutil dump -publics -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -globals -symbols %t.pdb | FileCheck %s # This tests the case where an __imp_ chunk is discarded by linker GC. The debug # info may refer to the __imp_ symbol still. @@ -11,12 +11,16 @@ # int discarded() { return __wc_mb_cur; } # int main() { return g2; } -# CHECK: Symbols -# CHECK: ============================================================ -# CHECK: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: -# CHECK: 4 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` -# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 -# CHECK: Mod 0001 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 32] `__imp___wc_mb_cur` +# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000 + +# CHECK: Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`: +# CHECK-NEXT: Mod 0001 | `* Linker *`: --- !COFF header: Index: lld/trunk/test/COFF/pdb-safeseh.yaml =================================================================== --- lld/trunk/test/COFF/pdb-safeseh.yaml +++ lld/trunk/test/COFF/pdb-safeseh.yaml @@ -1,16 +1,17 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s # There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in # it in this debug info. This is similar to the relocations in the loadcfg.obj # file in the MSVC CRT. We need to make sure that our relocation logic matches # MSVC's for these absolute, linker-provided symbols. -# CHECK: Mod 0000 | -# CHECK-NEXT: 4 | S_GDATA32 [size = 40] `___safe_se_handler_table` -# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 -# CHECK-NEXT: Mod 0001 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 40] `___safe_se_handler_table` +# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 --- !COFF header: Index: lld/trunk/test/COFF/pdb-secrel-absolute.yaml =================================================================== --- lld/trunk/test/COFF/pdb-secrel-absolute.yaml +++ lld/trunk/test/COFF/pdb-secrel-absolute.yaml @@ -1,16 +1,17 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s # There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in # it in this debug info. This is similar to the relocations in the loadcfg.obj # file in the MSVC CRT. We need to make sure that our relocation logic matches # MSVC's for these absolute, linker-provided symbols. -# CHECK: Mod 0000 | -# CHECK-NEXT: 4 | S_GDATA32 [size = 36] `__guard_fids_table` -# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 -# CHECK-NEXT: Mod 0001 | `* Linker *`: +# CHECK: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 20 | S_GDATA32 [size = 36] `__guard_fids_table` +# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000 --- !COFF header: Index: lld/trunk/test/COFF/pdb-symbol-types.yaml =================================================================== --- lld/trunk/test/COFF/pdb-symbol-types.yaml +++ lld/trunk/test/COFF/pdb-symbol-types.yaml @@ -1,6 +1,6 @@ # RUN: yaml2obj %s -o %t.obj # RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb -# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s +# RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s # To regenerate the object file: # $ cat symbol-types.c @@ -13,6 +13,18 @@ # Note that the type of 'global' goes from 0x1005 in the object file to 0x1004 # in the PDB because the LF_FUNC_ID is moved to the id stream. +# CHECK-LABEL: Global Symbols +# CHECK-NEXT: ============================================================ +# CHECK-NEXT: Records +# CHECK-NEXT: 48 | S_PROCREF [size = 20] `main` +# CHECK-NEXT: module = 1, sum name = 0, offset = 116 +# CHECK-NEXT: 96 | S_UDT [size = 16] `UDT_Foo` +# CHECK-NEXT: original type = 0x1004 +# CHECK-NEXT: 112 | S_UDT [size = 12] `Foo` +# CHECK-NEXT: original type = 0x1004 +# CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo` +# CHECK-NEXT: type = 0x1004 (Foo), addr = 0001:0000 + # CHECK: Symbols # CHECK: ============================================================ # CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`: @@ -29,13 +41,7 @@ # CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 # CHECK: flags = has async eh | opt speed # CHECK: 192 | S_END [size = 4] -# CHECK: 196 | S_GDATA32 [size = 28] `global_foo` -# CHECK: type = 0x1004 (Foo), addr = 0001:0000 -# CHECK: 224 | S_UDT [size = 16] `UDT_Foo` -# CHECK: original type = 0x1004 -# CHECK: 240 | S_UDT [size = 12] `Foo` -# CHECK: original type = 0x1004 -# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `0x100A` +# CHECK: 196 | S_BUILDINFO [size = 8] BuildId = `0x100A` # CHECK-LABEL: Mod 0001 | `* Linker *`: --- !COFF Index: lld/trunk/test/COFF/pdb-type-server-simple.test =================================================================== --- lld/trunk/test/COFF/pdb-type-server-simple.test +++ lld/trunk/test/COFF/pdb-type-server-simple.test @@ -21,7 +21,7 @@ RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib -RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s +RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s CHECK-LABEL: Types (TPI Stream) @@ -59,6 +59,18 @@ CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28] CHECK: {{.*}}: `b.c` +CHECK-LABEL: Global Symbols +CHECK: ============================================================ +CHECK-NEXT: Records +CHECK-NEXT: 36 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 104 +CHECK-NEXT: 68 | S_PROCREF [size = 16] `g` +CHECK-NEXT: module = 2, sum name = 0, offset = 104 +CHECK-NEXT: 56 | S_UDT [size = 12] `Foo` +CHECK-NEXT: original type = 0x1006 +CHECK-NEXT: 84 | S_UDT [size = 12] `Foo` +CHECK-NEXT: original type = 0x1006 + CHECK-LABEL: Symbols CHECK: ============================================================ CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: @@ -66,9 +78,7 @@ CHECK: 104 | S_GPROC32 [size = 44] `main` CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27 CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none -CHECK: 200 | S_UDT [size = 12] `Foo` -CHECK: original type = [[FOO_COMPLETE]] -CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj` CHECK: 44 | S_COMPILE3 [size = 60] @@ -85,7 +95,5 @@ CHECK: 180 | S_REGREL32 [size = 16] `p` CHECK: type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8 CHECK: 196 | S_END [size = 4] -CHECK: 200 | S_UDT [size = 12] `Foo` -CHECK: original type = [[FOO_COMPLETE]] -CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` +CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` CHECK-LABEL: Mod 0002 | `* Linker *`: Index: llvm/trunk/include/llvm/DebugInfo/CodeView/RecordName.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/RecordName.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/RecordName.h @@ -0,0 +1,24 @@ +//===- RecordName.h ------------------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDNAME_H +#define LLVM_DEBUGINFO_CODEVIEW_RECORDNAME_H + +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/TypeCollection.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" + +namespace llvm { +namespace codeview { +std::string computeTypeName(TypeCollection &Types, TypeIndex Index); +StringRef getSymbolName(CVSymbol Sym); +} // namespace codeview +} // namespace llvm + +#endif Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -54,14 +54,12 @@ template static Expected deserializeAs(ArrayRef Data) { - CVType CVT; - CVT.RecordData = Data; - MappingInfo I(CVT.content()); const RecordPrefix *Prefix = reinterpret_cast(Data.data()); TypeRecordKind K = static_cast(uint16_t(Prefix->RecordKind)); T Record(K); + CVType CVT(static_cast(K), Data); if (auto EC = deserializeAs(CVT, Record)) return std::move(EC); return Record; Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h @@ -1,22 +0,0 @@ -//===- TypeName.h --------------------------------------------- *- C++ --*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H -#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H - -#include "llvm/DebugInfo/CodeView/TypeCollection.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" - -namespace llvm { -namespace codeview { -std::string computeTypeName(TypeCollection &Types, TypeIndex Index); -} -} // namespace llvm - -#endif Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -412,6 +412,10 @@ return (Options & ClassOptions::HasUniqueName) != ClassOptions::None; } + bool isNested() const { + return (Options & ClassOptions::Nested) != ClassOptions::None; + } + uint16_t getMemberCount() const { return MemberCount; } ClassOptions getOptions() const { return Options; } TypeIndex getFieldList() const { return FieldList; } Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h @@ -58,6 +58,12 @@ void addPublicSymbol(const codeview::PublicSym32 &Pub); + void addGlobalSymbol(const codeview::ProcRefSym &Sym); + void addGlobalSymbol(const codeview::DataSym &Sym); + void addGlobalSymbol(const codeview::ConstantSym &Sym); + void addGlobalSymbol(const codeview::UDTSym &Sym); + void addGlobalSymbol(const codeview::CVSymbol &Sym); + private: uint32_t calculatePublicsHashStreamSize() const; uint32_t calculateGlobalsHashStreamSize() const; Index: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt +++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt @@ -19,6 +19,7 @@ Formatters.cpp LazyRandomTypeCollection.cpp Line.cpp + RecordName.cpp RecordSerialization.cpp StringsAndChecksums.cpp SymbolRecordMapping.cpp @@ -27,7 +28,6 @@ TypeDumpVisitor.cpp TypeIndex.cpp TypeIndexDiscovery.cpp - TypeName.cpp TypeRecordMapping.cpp TypeSerializer.cpp TypeStreamMerger.cpp Index: llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -13,7 +13,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/CodeView/TypeName.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Endian.h" Index: llvm/trunk/lib/DebugInfo/CodeView/RecordName.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/RecordName.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/RecordName.cpp @@ -0,0 +1,320 @@ +//===- RecordName.cpp ----------------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/RecordName.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/Support/FormatVariadic.h" + +using namespace llvm; +using namespace llvm::codeview; + +namespace { +class TypeNameComputer : public TypeVisitorCallbacks { + /// The type collection. Used to calculate names of nested types. + TypeCollection &Types; + TypeIndex CurrentTypeIndex = TypeIndex::None(); + + /// Name of the current type. Only valid before visitTypeEnd. + SmallString<256> Name; + +public: + explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {} + + StringRef name() const { return Name; } + + /// Paired begin/end actions for all types. Receives all record data, + /// including the fixed-length record prefix. + Error visitTypeBegin(CVType &Record) override; + Error visitTypeBegin(CVType &Record, TypeIndex Index) override; + Error visitTypeEnd(CVType &Record) override; + +#define TYPE_RECORD(EnumName, EnumVal, Name) \ + Error visitKnownRecord(CVType &CVR, Name##Record &Record) override; +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#define MEMBER_RECORD(EnumName, EnumVal, Name) +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +}; +} // namespace + +Error TypeNameComputer::visitTypeBegin(CVType &Record) { + llvm_unreachable("Must call visitTypeBegin with a TypeIndex!"); + return Error::success(); +} + +Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) { + // Reset Name to the empty string. If the visitor sets it, we know it. + Name = ""; + CurrentTypeIndex = Index; + return Error::success(); +} + +Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); } + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, + FieldListRecord &FieldList) { + Name = ""; + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVRecord &CVR, + StringIdRecord &String) { + Name = String.getString(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) { + auto Indices = Args.getIndices(); + uint32_t Size = Indices.size(); + Name = "("; + for (uint32_t I = 0; I < Size; ++I) { + assert(Indices[I] < CurrentTypeIndex); + + Name.append(Types.getTypeName(Indices[I])); + if (I + 1 != Size) + Name.append(", "); + } + Name.push_back(')'); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, + StringListRecord &Strings) { + auto Indices = Strings.getIndices(); + uint32_t Size = Indices.size(); + Name = "\""; + for (uint32_t I = 0; I < Size; ++I) { + Name.append(Types.getTypeName(Indices[I])); + if (I + 1 != Size) + Name.append("\" \""); + } + Name.push_back('\"'); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) { + Name = Class.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) { + Name = Union.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) { + Name = Enum.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) { + Name = AT.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) { + Name = VFT.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) { + Name = Id.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) { + StringRef Ret = Types.getTypeName(Proc.getReturnType()); + StringRef Params = Types.getTypeName(Proc.getArgumentList()); + Name = formatv("{0} {1}", Ret, Params).sstr<256>(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, + MemberFunctionRecord &MF) { + StringRef Ret = Types.getTypeName(MF.getReturnType()); + StringRef Class = Types.getTypeName(MF.getClassType()); + StringRef Params = Types.getTypeName(MF.getArgumentList()); + Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) { + Name = Func.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) { + Name = TS.getName(); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) { + + if (Ptr.isPointerToMember()) { + const MemberPointerInfo &MI = Ptr.getMemberInfo(); + + StringRef Pointee = Types.getTypeName(Ptr.getReferentType()); + StringRef Class = Types.getTypeName(MI.getContainingType()); + Name = formatv("{0} {1}::*", Pointee, Class); + } else { + if (Ptr.isConst()) + Name.append("const "); + if (Ptr.isVolatile()) + Name.append("volatile "); + if (Ptr.isUnaligned()) + Name.append("__unaligned "); + + Name.append(Types.getTypeName(Ptr.getReferentType())); + + if (Ptr.getMode() == PointerMode::LValueReference) + Name.append("&"); + else if (Ptr.getMode() == PointerMode::RValueReference) + Name.append("&&"); + else if (Ptr.getMode() == PointerMode::Pointer) + Name.append("*"); + } + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) { + uint16_t Mods = static_cast(Mod.getModifiers()); + + SmallString<256> TypeName; + if (Mods & uint16_t(ModifierOptions::Const)) + Name.append("const "); + if (Mods & uint16_t(ModifierOptions::Volatile)) + Name.append("volatile "); + if (Mods & uint16_t(ModifierOptions::Unaligned)) + Name.append("__unaligned "); + Name.append(Types.getTypeName(Mod.getModifiedType())); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, + VFTableShapeRecord &Shape) { + Name = formatv("", Shape.getEntryCount()); + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord( + CVType &CVR, UdtModSourceLineRecord &ModSourceLine) { + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, + UdtSourceLineRecord &SourceLine) { + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) { + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, + MethodOverloadListRecord &Overloads) { + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) { + return Error::success(); +} + +Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) { + return Error::success(); +} + +std::string llvm::codeview::computeTypeName(TypeCollection &Types, + TypeIndex Index) { + TypeNameComputer Computer(Types); + CVType Record = Types.getType(Index); + if (auto EC = visitTypeRecord(Record, Index, Computer)) { + consumeError(std::move(EC)); + return ""; + } + return Computer.name(); +} + +static int getSymbolNameOffset(CVSymbol Sym) { + switch (Sym.kind()) { + // See ProcSym + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + case SymbolKind::S_GPROC32_ID: + case SymbolKind::S_LPROC32_ID: + case SymbolKind::S_LPROC32_DPC: + case SymbolKind::S_LPROC32_DPC_ID: + return 35; + // See Thunk32Sym + case SymbolKind::S_THUNK32: + return 21; + // See SectionSym + case SymbolKind::S_SECTION: + return 16; + // See CoffGroupSym + case SymbolKind::S_COFFGROUP: + return 14; + // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym + case SymbolKind::S_PUB32: + case SymbolKind::S_FILESTATIC: + case SymbolKind::S_REGREL32: + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: + case SymbolKind::S_LMANDATA: + case SymbolKind::S_GMANDATA: + case SymbolKind::S_LTHREAD32: + case SymbolKind::S_GTHREAD32: + return 10; + // See RegisterSym and LocalSym + case SymbolKind::S_REGISTER: + case SymbolKind::S_LOCAL: + return 6; + // See BlockSym + case SymbolKind::S_BLOCK32: + return 18; + // See LabelSym + case SymbolKind::S_LABEL32: + return 7; + // See ObjNameSym, ExportSym, and UDTSym + case SymbolKind::S_OBJNAME: + case SymbolKind::S_EXPORT: + case SymbolKind::S_UDT: + return 4; + // See BPRelativeSym + case SymbolKind::S_BPREL32: + return 8; + default: + return -1; + } +} + +StringRef llvm::codeview::getSymbolName(CVSymbol Sym) { + if (Sym.kind() == SymbolKind::S_CONSTANT) { + // S_CONSTANT is preceded by an APSInt, which has a variable length. So we + // have to do a full deserialization. + BinaryStreamReader Reader(Sym.content(), llvm::support::little); + // The container doesn't matter for single records. + SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile); + ConstantSym Const(SymbolKind::S_CONSTANT); + cantFail(Mapping.visitSymbolBegin(Sym)); + cantFail(Mapping.visitKnownRecord(Sym, Const)); + cantFail(Mapping.visitSymbolEnd(Sym)); + return Const.Name; + } + + int Offset = getSymbolNameOffset(Sym); + if (Offset == -1) + return StringRef(); + + StringRef StringData = toStringRef(Sym.content()).drop_front(Offset); + return StringData.split('\0').first; +} Index: llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp @@ -1,243 +0,0 @@ -//===- TypeName.cpp ------------------------------------------- *- C++ --*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/CodeView/TypeName.h" - -#include "llvm/ADT/SmallString.h" -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/Support/FormatVariadic.h" - -using namespace llvm; -using namespace llvm::codeview; - -namespace { -class TypeNameComputer : public TypeVisitorCallbacks { - /// The type collection. Used to calculate names of nested types. - TypeCollection &Types; - TypeIndex CurrentTypeIndex = TypeIndex::None(); - - /// Name of the current type. Only valid before visitTypeEnd. - SmallString<256> Name; - -public: - explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {} - - StringRef name() const { return Name; } - - /// Paired begin/end actions for all types. Receives all record data, - /// including the fixed-length record prefix. - Error visitTypeBegin(CVType &Record) override; - Error visitTypeBegin(CVType &Record, TypeIndex Index) override; - Error visitTypeEnd(CVType &Record) override; - -#define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(CVType &CVR, Name##Record &Record) override; -#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#define MEMBER_RECORD(EnumName, EnumVal, Name) -#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" -}; -} // namespace - -Error TypeNameComputer::visitTypeBegin(CVType &Record) { - llvm_unreachable("Must call visitTypeBegin with a TypeIndex!"); - return Error::success(); -} - -Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) { - // Reset Name to the empty string. If the visitor sets it, we know it. - Name = ""; - CurrentTypeIndex = Index; - return Error::success(); -} - -Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); } - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, - FieldListRecord &FieldList) { - Name = ""; - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVRecord &CVR, - StringIdRecord &String) { - Name = String.getString(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) { - auto Indices = Args.getIndices(); - uint32_t Size = Indices.size(); - Name = "("; - for (uint32_t I = 0; I < Size; ++I) { - assert(Indices[I] < CurrentTypeIndex); - - Name.append(Types.getTypeName(Indices[I])); - if (I + 1 != Size) - Name.append(", "); - } - Name.push_back(')'); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, - StringListRecord &Strings) { - auto Indices = Strings.getIndices(); - uint32_t Size = Indices.size(); - Name = "\""; - for (uint32_t I = 0; I < Size; ++I) { - Name.append(Types.getTypeName(Indices[I])); - if (I + 1 != Size) - Name.append("\" \""); - } - Name.push_back('\"'); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) { - Name = Class.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) { - Name = Union.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) { - Name = Enum.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) { - Name = AT.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) { - Name = VFT.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) { - Name = Id.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) { - StringRef Ret = Types.getTypeName(Proc.getReturnType()); - StringRef Params = Types.getTypeName(Proc.getArgumentList()); - Name = formatv("{0} {1}", Ret, Params).sstr<256>(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, - MemberFunctionRecord &MF) { - StringRef Ret = Types.getTypeName(MF.getReturnType()); - StringRef Class = Types.getTypeName(MF.getClassType()); - StringRef Params = Types.getTypeName(MF.getArgumentList()); - Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) { - Name = Func.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) { - Name = TS.getName(); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) { - - if (Ptr.isPointerToMember()) { - const MemberPointerInfo &MI = Ptr.getMemberInfo(); - - StringRef Pointee = Types.getTypeName(Ptr.getReferentType()); - StringRef Class = Types.getTypeName(MI.getContainingType()); - Name = formatv("{0} {1}::*", Pointee, Class); - } else { - if (Ptr.isConst()) - Name.append("const "); - if (Ptr.isVolatile()) - Name.append("volatile "); - if (Ptr.isUnaligned()) - Name.append("__unaligned "); - - Name.append(Types.getTypeName(Ptr.getReferentType())); - - if (Ptr.getMode() == PointerMode::LValueReference) - Name.append("&"); - else if (Ptr.getMode() == PointerMode::RValueReference) - Name.append("&&"); - else if (Ptr.getMode() == PointerMode::Pointer) - Name.append("*"); - } - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) { - uint16_t Mods = static_cast(Mod.getModifiers()); - - SmallString<256> TypeName; - if (Mods & uint16_t(ModifierOptions::Const)) - Name.append("const "); - if (Mods & uint16_t(ModifierOptions::Volatile)) - Name.append("volatile "); - if (Mods & uint16_t(ModifierOptions::Unaligned)) - Name.append("__unaligned "); - Name.append(Types.getTypeName(Mod.getModifiedType())); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, - VFTableShapeRecord &Shape) { - Name = formatv("", Shape.getEntryCount()); - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord( - CVType &CVR, UdtModSourceLineRecord &ModSourceLine) { - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, - UdtSourceLineRecord &SourceLine) { - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) { - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, - MethodOverloadListRecord &Overloads) { - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) { - return Error::success(); -} - -Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) { - return Error::success(); -} - -std::string llvm::codeview::computeTypeName(TypeCollection &Types, - TypeIndex Index) { - TypeNameComputer Computer(Types); - CVType Record = Types.getType(Index); - if (auto EC = visitTypeRecord(Record, Index, Computer)) { - consumeError(std::move(EC)); - return ""; - } - return Computer.name(); -} Index: llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp @@ -10,7 +10,7 @@ #include "llvm/DebugInfo/CodeView/TypeTableCollection.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/TypeName.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamReader.h" Index: llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" @@ -27,13 +28,6 @@ using namespace llvm::pdb; using namespace llvm::codeview; -static StringRef getSymbolName(const CVSymbol &Sym) { - assert(Sym.kind() == S_PUB32 && "handle other kinds"); - PublicSym32 PSL = - cantFail(SymbolDeserializer::deserializeAs(Sym)); - return PSL.Name; -} - struct llvm::pdb::GSIHashStreamBuilder { std::vector Records; uint32_t StreamIndex; @@ -45,6 +39,13 @@ uint32_t calculateRecordByteSize() const; Error commit(BinaryStreamWriter &Writer); void finalizeBuckets(uint32_t RecordZeroOffset); + + template void addSymbol(const T &Symbol, MSFBuilder &Msf) { + T Copy(Symbol); + Records.push_back(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(), + CodeViewContainer::Pdb)); + } + void addSymbol(const CVSymbol &Symbol) { Records.push_back(Symbol); } }; uint32_t GSIHashStreamBuilder::calculateSerializedLength() const { @@ -222,9 +223,27 @@ } void GSIStreamBuilder::addPublicSymbol(const PublicSym32 &Pub) { - PublicSym32 Copy(Pub); - PSH->Records.push_back(SymbolSerializer::writeOneSymbol( - Copy, Msf.getAllocator(), CodeViewContainer::Pdb)); + PSH->addSymbol(Pub, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const ProcRefSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const DataSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const UDTSym &Sym) { + GSH->addSymbol(Sym, Msf); +} + +void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Sym) { + GSH->addSymbol(Sym); } static Error writeRecords(BinaryStreamWriter &Writer,