1//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H 10#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H 11 12#include "lldb/Expression/DWARFExpression.h" 13#include "lldb/Symbol/Variable.h" 14#include "lldb/lldb-enumerations.h" 15 16#include "llvm/ADT/Optional.h" 17#include "llvm/DebugInfo/CodeView/CodeView.h" 18#include "llvm/DebugInfo/CodeView/SymbolRecord.h" 19#include "llvm/DebugInfo/CodeView/TypeRecord.h" 20#include "llvm/DebugInfo/PDB/PDBTypes.h" 21 22#include "PdbSymUid.h" 23 24#include <tuple> 25#include <utility> 26 27namespace llvm { 28namespace pdb { 29class TpiStream; 30} 31} // namespace llvm 32 33namespace lldb_private { 34namespace npdb { 35 36class PdbIndex; 37 38struct CVTagRecord { 39 enum Kind { Class, Struct, Union, Enum }; 40 41 static CVTagRecord create(llvm::codeview::CVType type); 42 43 Kind kind() const { return m_kind; } 44 45 const llvm::codeview::TagRecord &asTag() const { 46 if (m_kind == Struct || m_kind == Class) 47 return cvclass; 48 if (m_kind == Enum) 49 return cvenum; 50 return cvunion; 51 } 52 53 const llvm::codeview::ClassRecord &asClass() const { 54 assert(m_kind == Struct || m_kind == Class); 55 return cvclass; 56 } 57 58 const llvm::codeview::EnumRecord &asEnum() const { 59 assert(m_kind == Enum); 60 return cvenum; 61 } 62 63 const llvm::codeview::UnionRecord &asUnion() const { 64 assert(m_kind == Union); 65 return cvunion; 66 } 67 68 llvm::StringRef name() const { 69 if (m_kind == Struct || m_kind == Union) 70 return cvclass.Name; 71 if (m_kind == Enum) 72 return cvenum.Name; 73 return cvunion.Name; 74 } 75 76private: 77 CVTagRecord(llvm::codeview::ClassRecord &&c); 78 CVTagRecord(llvm::codeview::UnionRecord &&u); 79 CVTagRecord(llvm::codeview::EnumRecord &&e); 80 union { 81 llvm::codeview::ClassRecord cvclass; 82 llvm::codeview::EnumRecord cvenum; 83 llvm::codeview::UnionRecord cvunion; 84 }; 85 Kind m_kind; 86}; 87 88struct SegmentOffset { 89 SegmentOffset() = default; 90 SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {} 91 uint16_t segment = 0; 92 uint32_t offset = 0; 93}; 94 95struct SegmentOffsetLength { 96 SegmentOffsetLength() = default; 97 SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l) 98 : so(s, o), length(l) {} 99 SegmentOffset so; 100 uint32_t length = 0; 101}; 102 103struct VariableInfo { 104 llvm::StringRef name; 105 llvm::codeview::TypeIndex type; 106 llvm::Optional<DWARFExpression> location; 107 llvm::Optional<Variable::RangeList> ranges; 108}; 109 110llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); 111llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind); 112 113bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym); 114bool SymbolIsCode(const llvm::codeview::CVSymbol &sym); 115 116SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym); 117SegmentOffsetLength 118GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym); 119 120template <typename RecordT> bool IsValidRecord(const RecordT &sym) { 121 return true; 122} 123 124inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { 125 // S_PROCREF symbols have 1-based module indices. 126 return sym.Module > 0; 127} 128 129bool IsForwardRefUdt(llvm::codeview::CVType cvt); 130bool IsTagRecord(llvm::codeview::CVType cvt); 131bool IsClassStructUnion(llvm::codeview::CVType cvt); 132 133bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); 134bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); 135 136lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access); 137llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt); 138llvm::codeview::TypeIndex 139LookThroughModifierRecord(llvm::codeview::CVType modifier); 140 141llvm::StringRef DropNameScope(llvm::StringRef name); 142 143VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol); 144VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block& block, 145 lldb::ModuleSP module); 146 147size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind); 148lldb::BasicType 149GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind); 150 151PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); 152 153size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); 154 155} // namespace npdb 156} // namespace lldb_private 157 158#endif 159