Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
                                           DataMemberRecord &data_member) {

  uint64_t offset = data_member.FieldOffset * 8;
  uint32_t bitfield_width = 0;

  TypeIndex ti(data_member.Type);
  if (!ti.isSimple()) {
    CVType cvt = m_tpi.getType(ti);
    if (cvt.kind() == LF_BITFIELD) {
      BitFieldRecord bfr;
      llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr));
      offset += bfr.BitOffset;
      bitfield_width = bfr.BitSize;
      ti = bfr.Type;
    }
  }

  clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti));
  m_ast_builder.CompleteType(member_qt);

  lldb::AccessType access = TranslateMemberAccess(data_member.getAccess());

  clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType(
      m_derived_ct, data_member.Name, m_ast_builder.ToCompilerType(member_qt),
      access, bitfield_width);
  // FIXME: Add a PdbSymUid namespace for field list members and update
  // the m_uid_to_decl map with this decl.

  m_layout.field_offsets.insert(std::make_pair(decl, offset));

  return Error::success();
}
Example #2
0
Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
  switch (Rec.kind()) {
  case LF_CLASS:
  case LF_STRUCTURE:
  case LF_INTERFACE:
    return getHashForUdt<ClassRecord>(Rec);
  case LF_UNION:
    return getHashForUdt<UnionRecord>(Rec);
  case LF_ENUM:
    return getHashForUdt<EnumRecord>(Rec);

  case LF_UDT_SRC_LINE:
    return getSourceLineHash<UdtSourceLineRecord>(Rec);
  case LF_UDT_MOD_SRC_LINE:
    return getSourceLineHash<UdtModSourceLineRecord>(Rec);

  default:
    break;
  }

  // Run CRC32 over the bytes. This corresponds to `hashBufv8`.
  JamCRC JC(/*Init=*/0U);
  ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()),
                       Rec.data().size());
  JC.update(Bytes);
  return JC.getCRC();
}
Example #3
0
Error TypeStreamMerger::remapType(const CVType &Type) {
  auto DoSerialize = [this, Type]() -> ArrayRef<uint8_t> {
    RemappedType R(Type);
    SmallVector<TiReference, 32> Refs;
    discoverTypeIndices(Type.RecordData, Refs);
    if (!remapIndices(R, Refs))
      return {};
    return serializeRemapped(R);
  };

  TypeIndex DestIdx = Untranslated;
  if (UseGlobalHashes) {
    GlobalTypeTableBuilder &Dest =
        isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
    GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
    DestIdx = Dest.insertRecordAs(H, DoSerialize);
  } else {
    MergingTypeTableBuilder &Dest =
        isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;

    auto Data = DoSerialize();
    if (!Data.empty())
      DestIdx = Dest.insertRecordBytes(Data);
  }
  addMapping(DestIdx);

  ++CurIndex;
  assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) &&
         "visitKnownRecord should add one index map entry");
  return Error::success();
}
static std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti,
                                                   TpiStream &tpi) {
  if (ti.isSimple()) {
    SimpleTypeKind stk = ti.getSimpleKind();
    return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)};
  }

  CVType cvt = tpi.getType(ti);
  switch (cvt.kind()) {
  case LF_MODIFIER: {
    ModifierRecord mfr;
    llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr));
    return GetIntegralTypeInfo(mfr.ModifiedType, tpi);
  }
  case LF_POINTER: {
    PointerRecord pr;
    llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
    return GetIntegralTypeInfo(pr.ReferentType, tpi);
  }
  case LF_ENUM: {
    EnumRecord er;
    llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
    return GetIntegralTypeInfo(er.UnderlyingType, tpi);
  }
  default:
    assert(false && "Type is not integral!");
    return {0, false};
  }
}
Example #5
0
static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
  TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind());
  T KnownRecord(RK);
  if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
    return EC;
  return Error::success();
}
Example #6
0
static Expected<uint32_t> getHashForUdt(const CVType &Rec) {
  T Deserialized;
  if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
                                               Deserialized))
    return std::move(E);
  return getHashForUdt(Deserialized, Rec.data());
}
Example #7
0
size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id,
                                         llvm::pdb::TpiStream &tpi) {
  if (id.index.isSimple()) {
    switch (id.index.getSimpleMode()) {
    case SimpleTypeMode::Direct:
      return GetTypeSizeForSimpleKind(id.index.getSimpleKind());
    case SimpleTypeMode::NearPointer32:
    case SimpleTypeMode::FarPointer32:
      return 4;
    case SimpleTypeMode::NearPointer64:
      return 8;
    case SimpleTypeMode::NearPointer128:
      return 16;
    default:
      break;
    }
    return 0;
  }

  TypeIndex index = id.index;
  if (IsForwardRefUdt(index, tpi))
    index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));

  CVType cvt = tpi.getType(index);
  switch (cvt.kind()) {
  case LF_MODIFIER:
    return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi);
  case LF_ENUM: {
    EnumRecord record;
    llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
    return GetSizeOfType({record.UnderlyingType}, tpi);
  }
  case LF_POINTER:
    return GetSizeOfTypeInternal<PointerRecord>(cvt);
  case LF_ARRAY:
    return GetSizeOfTypeInternal<ArrayRecord>(cvt);
  case LF_CLASS:
  case LF_STRUCTURE:
  case LF_INTERFACE:
    return GetSizeOfTypeInternal<ClassRecord>(cvt);
  case LF_UNION:
    return GetSizeOfTypeInternal<UnionRecord>(cvt);
  default:
    break;
  }
  return 0;
}
Example #8
0
Error TypeDumpVisitor::visitTypeEnd(CVType &Record) {
  if (PrintRecordBytes)
    W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));

  W->unindent();
  W->startLine() << "}\n";
  return Error::success();
}
Example #9
0
static inline Expected<LeafRecord> fromCodeViewRecordImpl(CVType Type) {
  LeafRecord Result;

  auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.kind());
  if (auto EC = Impl->fromCodeViewRecord(Type))
    return std::move(EC);
  Result.Leaf = Impl;
  return Result;
}
Example #10
0
ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugT(ArrayRef<LeafRecord> Leafs,
                                               BumpPtrAllocator &Alloc) {
  TypeTableBuilder TTB(Alloc, false);
  uint32_t Size = sizeof(uint32_t);
  for (const auto &Leaf : Leafs) {
    CVType T = Leaf.toCodeViewRecord(TTB);
    Size += T.length();
    assert(T.length() % 4 == 0 && "Improper type record alignment!");
  }
  uint8_t *ResultBuffer = Alloc.Allocate<uint8_t>(Size);
  MutableArrayRef<uint8_t> Output(ResultBuffer, Size);
  BinaryStreamWriter Writer(Output, support::little);
  ExitOnError Err("Error writing type record to .debug$T section");
  Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC));
  for (const auto &R : TTB.records()) {
    Err(Writer.writeBytes(R));
  }
  assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!");
  return Output;
}
Example #11
0
Expected<LeafRecord> LeafRecord::fromCodeViewRecord(CVType Type) {
#define TYPE_RECORD(EnumName, EnumVal, ClassName)                              \
  case EnumName:                                                               \
    return fromCodeViewRecordImpl<ClassName##Record>(Type);
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)             \
  TYPE_RECORD(EnumName, EnumVal, ClassName)
#define MEMBER_RECORD(EnumName, EnumVal, ClassName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)
  switch (Type.kind()) {
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
  default: { llvm_unreachable("Unknown leaf kind!"); }
  }
  return make_error<CodeViewError>(cv_error_code::corrupt_record);
}
UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id,
                                       CompilerType &derived_ct,
                                       clang::TagDecl &tag_decl,
                                       PdbAstBuilder &ast_builder,
                                       TpiStream &tpi)
    : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
      m_ast_builder(ast_builder), m_tpi(tpi) {
  CVType cvt = m_tpi.getType(m_id.index);
  switch (cvt.kind()) {
  case LF_ENUM:
    llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er));
    break;
  case LF_UNION:
    llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, m_cvr.ur));
    break;
  case LF_CLASS:
  case LF_STRUCTURE:
    llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, m_cvr.cr));
    break;
  default:
    llvm_unreachable("unreachable!");
  }
}
bool llvm::codeview::isUdtForwardRef(CVType CVT) {
  ClassOptions UdtOptions = ClassOptions::None;
  switch (CVT.kind()) {
  case LF_STRUCTURE:
  case LF_CLASS:
  case LF_INTERFACE:
    UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT));
    break;
  case LF_ENUM:
    UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT));
    break;
  case LF_UNION:
    UdtOptions = getUdtOptions<UnionRecord>(std::move(CVT));
    break;
  default:
    return false;
  }
  return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None;
}
Example #14
0
bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) {
  ClassRecord cr;
  UnionRecord ur;
  EnumRecord er;
  switch (cvt.kind()) {
  case LF_CLASS:
  case LF_STRUCTURE:
  case LF_INTERFACE:
    llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
    return cr.isForwardRef();
  case LF_UNION:
    llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
    return ur.isForwardRef();
  case LF_ENUM:
    llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
    return er.isForwardRef();
  default:
    return false;
  }
}
Example #15
0
TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) {
  switch (cvt.kind()) {
  case LF_CLASS:
  case LF_STRUCTURE:
  case LF_INTERFACE: {
    ClassRecord cr;
    cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
    return cr.FieldList;
  }
  case LF_UNION: {
    UnionRecord ur;
    cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
    return ur.FieldList;
  }
  case LF_ENUM: {
    EnumRecord er;
    cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
    return er.FieldList;
  }
  default:
    llvm_unreachable("Unreachable!");
  }
}
Example #16
0
CVTagRecord CVTagRecord::create(CVType type) {
  assert(IsTagRecord(type) && "type is not a tag record!");
  switch (type.kind()) {
  case LF_CLASS:
  case LF_STRUCTURE:
  case LF_INTERFACE: {
    ClassRecord cr;
    llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
    return CVTagRecord(std::move(cr));
  }
  case LF_UNION: {
    UnionRecord ur;
    llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
    return CVTagRecord(std::move(ur));
  }
  case LF_ENUM: {
    EnumRecord er;
    llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
    return CVTagRecord(std::move(er));
  }
  default:
    llvm_unreachable("Unreachable!");
  }
}
Example #17
0
//Special override for CVImageType
PrecisionType * GetFirstPointer(CVImageType::Pointer in)
{
  CVType * firstCovariantVectorX = in->GetBufferPointer();
  return  firstCovariantVectorX->GetDataPointer();
}
Example #18
0
Error LeafRecordImpl<FieldListRecord>::fromCodeViewRecord(CVType Type) {
  MemberRecordConversionVisitor V(Members);
  return visitMemberRecordStream(Type.content(), V);
}
TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) {
  assert(CVT.kind() == LF_MODIFIER);
  SmallVector<TypeIndex, 1> Refs;
  discoverTypeIndices(CVT, Refs);
  return Refs.front();
}
Example #20
0
 static ArrayRef<uint8_t> bytes(const CVType &Item) { return Item.data(); }
Example #21
0
Error TypeDumpVisitor::visitUnknownType(CVType &Record) {
  W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames));
  W->printNumber("Length", uint32_t(Record.content().size()));
  return Error::success();
}
Example #22
0
TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) {
  lldbassert(modifier.kind() == LF_MODIFIER);
  ModifierRecord mr;
  llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
  return mr.ModifiedType;
}
Example #23
0
void llvm::codeview::discoverTypeIndices(const CVType &Type,
                                         SmallVectorImpl<TiReference> &Refs) {
  ::discoverTypeIndices(Type.content(), Type.kind(), Refs);
}
Example #24
0
 static size_t length(const CVType &Item) { return Item.length(); }