Originally we created our 64-bit UID scheme by using the first byte as sort of a "tag" to represent what kind of symbol this was, and we re-used the PDB_SymType enumeration for this. For native pdb support, this is not really the right abstraction layer, because what we really want is something that tells us *how* to find the symbol. This means, specifically, is in the globals stream / public stream / module stream / TPI stream / etc, and for whichever one it is in, where is it within that stream? A good example of why the old namespacing scheme was insufficient is that it is more or less impossible to create a uid for a field list member of a class/struction/union/enum that tells you how to locate the original record. With this new scheme, the first byte is no longer a PDB_SymType enum but a new enum created specifically to identify where in the PDB this record lives. This gives us much better flexibility in what kinds of symbols the uids can identify. llvm-svn: 347018
126 lines
3.3 KiB
C++
126 lines
3.3 KiB
C++
//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
|
|
#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
|
|
|
|
#include "lldb/lldb-enumerations.h"
|
|
|
|
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
|
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
|
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
|
|
|
#include <tuple>
|
|
#include <utility>
|
|
|
|
namespace llvm {
|
|
namespace pdb {
|
|
class TpiStream;
|
|
}
|
|
} // namespace llvm
|
|
|
|
namespace lldb_private {
|
|
namespace npdb {
|
|
|
|
struct PdbTypeSymId;
|
|
|
|
struct CVTagRecord {
|
|
enum Kind { Class, Struct, Union, Enum };
|
|
|
|
static CVTagRecord create(llvm::codeview::CVType type);
|
|
|
|
Kind kind() const { return m_kind; }
|
|
|
|
const llvm::codeview::TagRecord &asTag() const {
|
|
if (m_kind == Struct || m_kind == Class)
|
|
return cvclass;
|
|
if (m_kind == Enum)
|
|
return cvenum;
|
|
return cvunion;
|
|
}
|
|
|
|
const llvm::codeview::ClassRecord &asClass() const {
|
|
assert(m_kind == Struct || m_kind == Class);
|
|
return cvclass;
|
|
}
|
|
|
|
const llvm::codeview::EnumRecord &asEnum() const {
|
|
assert(m_kind == Enum);
|
|
return cvenum;
|
|
}
|
|
|
|
const llvm::codeview::UnionRecord &asUnion() const {
|
|
assert(m_kind == Union);
|
|
return cvunion;
|
|
}
|
|
|
|
private:
|
|
CVTagRecord(llvm::codeview::ClassRecord &&c);
|
|
CVTagRecord(llvm::codeview::UnionRecord &&u);
|
|
CVTagRecord(llvm::codeview::EnumRecord &&e);
|
|
union {
|
|
llvm::codeview::ClassRecord cvclass;
|
|
llvm::codeview::EnumRecord cvenum;
|
|
llvm::codeview::UnionRecord cvunion;
|
|
};
|
|
Kind m_kind;
|
|
};
|
|
|
|
struct SegmentOffset {
|
|
SegmentOffset() = default;
|
|
SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {}
|
|
uint16_t segment = 0;
|
|
uint32_t offset = 0;
|
|
};
|
|
|
|
struct SegmentOffsetLength {
|
|
SegmentOffsetLength() = default;
|
|
SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l)
|
|
: so(s, o), length(l) {}
|
|
SegmentOffset so;
|
|
uint32_t length = 0;
|
|
};
|
|
|
|
llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
|
|
llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
|
|
|
|
bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
|
|
bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
|
|
|
|
SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
|
|
SegmentOffsetLength
|
|
GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
|
|
|
|
template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
|
|
return true;
|
|
}
|
|
|
|
inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
|
|
// S_PROCREF symbols have 1-based module indices.
|
|
return sym.Module > 0;
|
|
}
|
|
|
|
bool IsForwardRefUdt(llvm::codeview::CVType cvt);
|
|
bool IsTagRecord(llvm::codeview::CVType cvt);
|
|
|
|
bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
|
|
bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
|
|
|
|
lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
|
|
llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
|
|
llvm::codeview::TypeIndex
|
|
LookThroughModifierRecord(llvm::codeview::CVType modifier);
|
|
|
|
llvm::StringRef DropNameScope(llvm::StringRef name);
|
|
|
|
} // namespace npdb
|
|
} // namespace lldb_private
|
|
|
|
#endif
|