10b57cec5SDimitry Andric //===-- PdbUtil.h -----------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H
105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "lldb/Expression/DWARFExpression.h"
130b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h"
140b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
170b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
180b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h"
190b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #include "PdbSymUid.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #include <tuple>
240b57cec5SDimitry Andric #include <utility>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace llvm {
270b57cec5SDimitry Andric namespace pdb {
280b57cec5SDimitry Andric class TpiStream;
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric } // namespace llvm
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric namespace lldb_private {
330b57cec5SDimitry Andric namespace npdb {
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric class PdbIndex;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric struct CVTagRecord {
380b57cec5SDimitry Andric   enum Kind { Class, Struct, Union, Enum };
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   static CVTagRecord create(llvm::codeview::CVType type);
410b57cec5SDimitry Andric 
kindCVTagRecord420b57cec5SDimitry Andric   Kind kind() const { return m_kind; }
430b57cec5SDimitry Andric 
asTagCVTagRecord440b57cec5SDimitry Andric   const llvm::codeview::TagRecord &asTag() const {
450b57cec5SDimitry Andric     if (m_kind == Struct || m_kind == Class)
460b57cec5SDimitry Andric       return cvclass;
470b57cec5SDimitry Andric     if (m_kind == Enum)
480b57cec5SDimitry Andric       return cvenum;
490b57cec5SDimitry Andric     return cvunion;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric 
asClassCVTagRecord520b57cec5SDimitry Andric   const llvm::codeview::ClassRecord &asClass() const {
530b57cec5SDimitry Andric     assert(m_kind == Struct || m_kind == Class);
540b57cec5SDimitry Andric     return cvclass;
550b57cec5SDimitry Andric   }
560b57cec5SDimitry Andric 
asEnumCVTagRecord570b57cec5SDimitry Andric   const llvm::codeview::EnumRecord &asEnum() const {
580b57cec5SDimitry Andric     assert(m_kind == Enum);
590b57cec5SDimitry Andric     return cvenum;
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric 
asUnionCVTagRecord620b57cec5SDimitry Andric   const llvm::codeview::UnionRecord &asUnion() const {
630b57cec5SDimitry Andric     assert(m_kind == Union);
640b57cec5SDimitry Andric     return cvunion;
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric 
nameCVTagRecord670b57cec5SDimitry Andric   llvm::StringRef name() const {
680b57cec5SDimitry Andric     if (m_kind == Struct || m_kind == Union)
690b57cec5SDimitry Andric       return cvclass.Name;
700b57cec5SDimitry Andric     if (m_kind == Enum)
710b57cec5SDimitry Andric       return cvenum.Name;
720b57cec5SDimitry Andric     return cvunion.Name;
730b57cec5SDimitry Andric   }
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric private:
760b57cec5SDimitry Andric   CVTagRecord(llvm::codeview::ClassRecord &&c);
770b57cec5SDimitry Andric   CVTagRecord(llvm::codeview::UnionRecord &&u);
780b57cec5SDimitry Andric   CVTagRecord(llvm::codeview::EnumRecord &&e);
790b57cec5SDimitry Andric   union {
800b57cec5SDimitry Andric     llvm::codeview::ClassRecord cvclass;
810b57cec5SDimitry Andric     llvm::codeview::EnumRecord cvenum;
820b57cec5SDimitry Andric     llvm::codeview::UnionRecord cvunion;
830b57cec5SDimitry Andric   };
840b57cec5SDimitry Andric   Kind m_kind;
850b57cec5SDimitry Andric };
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric struct SegmentOffset {
880b57cec5SDimitry Andric   SegmentOffset() = default;
SegmentOffsetSegmentOffset890b57cec5SDimitry Andric   SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {}
900b57cec5SDimitry Andric   uint16_t segment = 0;
910b57cec5SDimitry Andric   uint32_t offset = 0;
920b57cec5SDimitry Andric };
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric struct SegmentOffsetLength {
950b57cec5SDimitry Andric   SegmentOffsetLength() = default;
SegmentOffsetLengthSegmentOffsetLength960b57cec5SDimitry Andric   SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l)
970b57cec5SDimitry Andric       : so(s, o), length(l) {}
980b57cec5SDimitry Andric   SegmentOffset so;
990b57cec5SDimitry Andric   uint32_t length = 0;
1000b57cec5SDimitry Andric };
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric struct VariableInfo {
1030b57cec5SDimitry Andric   llvm::StringRef name;
1040b57cec5SDimitry Andric   llvm::codeview::TypeIndex type;
105bdd1243dSDimitry Andric   DWARFExpressionList location;
10681ad6265SDimitry Andric   bool is_param;
1070b57cec5SDimitry Andric };
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
1100b57cec5SDimitry Andric llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
1130b57cec5SDimitry Andric bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
1160b57cec5SDimitry Andric SegmentOffsetLength
1170b57cec5SDimitry Andric GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
1180b57cec5SDimitry Andric 
IsValidRecord(const RecordT & sym)1190b57cec5SDimitry Andric template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
1200b57cec5SDimitry Andric   return true;
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
IsValidRecord(const llvm::codeview::ProcRefSym & sym)1230b57cec5SDimitry Andric inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
1240b57cec5SDimitry Andric   // S_PROCREF symbols have 1-based module indices.
1250b57cec5SDimitry Andric   return sym.Module > 0;
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric bool IsForwardRefUdt(llvm::codeview::CVType cvt);
1290b57cec5SDimitry Andric bool IsTagRecord(llvm::codeview::CVType cvt);
1300b57cec5SDimitry Andric bool IsClassStructUnion(llvm::codeview::CVType cvt);
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
1330b57cec5SDimitry Andric bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
1360b57cec5SDimitry Andric llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
1370b57cec5SDimitry Andric llvm::codeview::TypeIndex
1380b57cec5SDimitry Andric LookThroughModifierRecord(llvm::codeview::CVType modifier);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric llvm::StringRef DropNameScope(llvm::StringRef name);
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
143753f127fSDimitry Andric VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id,
144753f127fSDimitry Andric                                      Block &func_block, lldb::ModuleSP module);
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
1470b57cec5SDimitry Andric lldb::BasicType
1480b57cec5SDimitry Andric GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric } // namespace npdb
1550b57cec5SDimitry Andric } // namespace lldb_private
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric #endif
158