161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- PdbSymUid.cpp -----------------------------------------------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "PdbSymUid.h"
 | |
| 
 | |
| using namespace lldb_private;
 | |
| using namespace lldb_private::npdb;
 | |
| using namespace llvm::codeview;
 | |
| 
 | |
| namespace {
 | |
| struct GenericIdRepr {
 | |
|   uint64_t tag : 4;
 | |
|   uint64_t data : 60;
 | |
| };
 | |
| 
 | |
| struct CompilandIdRepr {
 | |
|   uint64_t tag : 4;
 | |
|   uint64_t modi : 16;
 | |
|   uint64_t unused : 44;
 | |
| };
 | |
| 
 | |
| struct CompilandSymIdRepr {
 | |
|   uint64_t tag : 4;
 | |
|   uint64_t modi : 16;
 | |
|   uint64_t offset : 32;
 | |
|   uint64_t unused : 12;
 | |
| };
 | |
| 
 | |
| struct GlobalSymIdRepr {
 | |
|   uint64_t tag : 4;
 | |
|   uint64_t offset : 32;
 | |
|   uint64_t pub : 1;
 | |
|   uint64_t unused : 27;
 | |
| };
 | |
| 
 | |
| struct TypeSymIdRepr {
 | |
|   uint64_t tag : 4;
 | |
|   uint64_t index : 32;
 | |
|   uint64_t ipi : 1;
 | |
|   uint64_t unused : 27;
 | |
| };
 | |
| 
 | |
| struct FieldListMemberIdRepr {
 | |
|   uint64_t tag : 4;
 | |
|   uint64_t index : 32;
 | |
|   uint64_t offset : 16;
 | |
|   uint64_t unused : 12;
 | |
| };
 | |
| 
 | |
| static_assert(sizeof(CompilandIdRepr) == 8, "Invalid structure size!");
 | |
| static_assert(sizeof(CompilandSymIdRepr) == 8, "Invalid structure size!");
 | |
| static_assert(sizeof(GlobalSymIdRepr) == 8, "Invalid structure size!");
 | |
| static_assert(sizeof(TypeSymIdRepr) == 8, "Invalid structure size!");
 | |
| static_assert(sizeof(FieldListMemberIdRepr) == 8, "Invalid structure size!");
 | |
| } // namespace
 | |
| 
 | |
| template <typename OutT, typename InT> static OutT repr_cast(const InT &value) {
 | |
|   OutT result;
 | |
|   ::memcpy(&result, &value, sizeof(value));
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| PdbSymUid::PdbSymUid(const PdbCompilandId &cid) {
 | |
|   CompilandIdRepr repr;
 | |
|   ::memset(&repr, 0, sizeof(repr));
 | |
|   repr.modi = cid.modi;
 | |
|   repr.tag = static_cast<uint64_t>(PdbSymUidKind::Compiland);
 | |
|   m_repr = repr_cast<uint64_t>(repr);
 | |
| }
 | |
| 
 | |
| PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) {
 | |
|   CompilandSymIdRepr repr;
 | |
|   ::memset(&repr, 0, sizeof(repr));
 | |
|   repr.modi = csid.modi;
 | |
|   repr.offset = csid.offset;
 | |
|   repr.tag = static_cast<uint64_t>(PdbSymUidKind::CompilandSym);
 | |
|   m_repr = repr_cast<uint64_t>(repr);
 | |
| }
 | |
| 
 | |
| PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) {
 | |
|   GlobalSymIdRepr repr;
 | |
|   ::memset(&repr, 0, sizeof(repr));
 | |
|   repr.pub = gsid.is_public;
 | |
|   repr.offset = gsid.offset;
 | |
|   repr.tag = static_cast<uint64_t>(PdbSymUidKind::GlobalSym);
 | |
|   m_repr = repr_cast<uint64_t>(repr);
 | |
| }
 | |
| 
 | |
| PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) {
 | |
|   TypeSymIdRepr repr;
 | |
|   ::memset(&repr, 0, sizeof(repr));
 | |
|   repr.index = tsid.index.getIndex();
 | |
|   repr.ipi = tsid.is_ipi;
 | |
|   repr.tag = static_cast<uint64_t>(PdbSymUidKind::Type);
 | |
|   m_repr = repr_cast<uint64_t>(repr);
 | |
| }
 | |
| 
 | |
| PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) {
 | |
|   FieldListMemberIdRepr repr;
 | |
|   ::memset(&repr, 0, sizeof(repr));
 | |
|   repr.index = flmid.index.getIndex();
 | |
|   repr.offset = flmid.offset;
 | |
|   repr.tag = static_cast<uint64_t>(PdbSymUidKind::FieldListMember);
 | |
|   m_repr = repr_cast<uint64_t>(repr);
 | |
| }
 | |
| 
 | |
| PdbSymUidKind PdbSymUid::kind() const {
 | |
|   GenericIdRepr generic = repr_cast<GenericIdRepr>(m_repr);
 | |
|   return static_cast<PdbSymUidKind>(generic.tag);
 | |
| }
 | |
| 
 | |
| PdbCompilandId PdbSymUid::asCompiland() const {
 | |
|   assert(kind() == PdbSymUidKind::Compiland);
 | |
|   auto repr = repr_cast<CompilandIdRepr>(m_repr);
 | |
|   PdbCompilandId result;
 | |
|   result.modi = repr.modi;
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| PdbCompilandSymId PdbSymUid::asCompilandSym() const {
 | |
|   assert(kind() == PdbSymUidKind::CompilandSym);
 | |
|   auto repr = repr_cast<CompilandSymIdRepr>(m_repr);
 | |
|   PdbCompilandSymId result;
 | |
|   result.modi = repr.modi;
 | |
|   result.offset = repr.offset;
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| PdbGlobalSymId PdbSymUid::asGlobalSym() const {
 | |
|   assert(kind() == PdbSymUidKind::GlobalSym ||
 | |
|          kind() == PdbSymUidKind::PublicSym);
 | |
|   auto repr = repr_cast<GlobalSymIdRepr>(m_repr);
 | |
|   PdbGlobalSymId result;
 | |
|   result.is_public = repr.pub;
 | |
|   result.offset = repr.offset;
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| PdbTypeSymId PdbSymUid::asTypeSym() const {
 | |
|   assert(kind() == PdbSymUidKind::Type);
 | |
|   auto repr = repr_cast<TypeSymIdRepr>(m_repr);
 | |
|   PdbTypeSymId result;
 | |
|   result.index.setIndex(repr.index);
 | |
|   result.is_ipi = repr.ipi;
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| PdbFieldListMemberId PdbSymUid::asFieldListMember() const {
 | |
|   assert(kind() == PdbSymUidKind::FieldListMember);
 | |
|   auto repr = repr_cast<FieldListMemberIdRepr>(m_repr);
 | |
|   PdbFieldListMemberId result;
 | |
|   result.index.setIndex(repr.index);
 | |
|   result.offset = repr.offset;
 | |
|   return result;
 | |
| }
 |