Пример #1
0
void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
                                             const VTableLayout &layout,
                                             llvm::Constant *rtti) {
  unsigned nextVTableThunkIndex = 0;
  for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i) {
    auto vtableElem = builder.beginArray(CGM.Int8PtrTy);
    size_t thisIndex = layout.getVTableOffset(i);
    size_t nextIndex = thisIndex + layout.getVTableSize(i);
    for (unsigned i = thisIndex; i != nextIndex; ++i) {
      addVTableComponent(vtableElem, layout, i, rtti, nextVTableThunkIndex);
    }
    vtableElem.finishAndAddTo(builder);
  }
}
Пример #2
0
void CodeGenModule::EmitVTableTypeMetadata(llvm::GlobalVariable *VTable,
                                           const VTableLayout &VTLayout) {
  if (!getCodeGenOpts().LTOUnit)
    return;

  CharUnits PointerWidth =
      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));

  typedef std::pair<const CXXRecordDecl *, unsigned> BSEntry;
  std::vector<BSEntry> BitsetEntries;
  // Create a bit set entry for each address point.
  for (auto &&AP : VTLayout.getAddressPoints())
    BitsetEntries.push_back(
        std::make_pair(AP.first.getBase(),
                       VTLayout.getVTableOffset(AP.second.VTableIndex) +
                           AP.second.AddressPointIndex));

  // Sort the bit set entries for determinism.
  std::sort(BitsetEntries.begin(), BitsetEntries.end(),
            [this](const BSEntry &E1, const BSEntry &E2) {
    if (&E1 == &E2)
      return false;

    std::string S1;
    llvm::raw_string_ostream O1(S1);
    getCXXABI().getMangleContext().mangleTypeName(
        QualType(E1.first->getTypeForDecl(), 0), O1);
    O1.flush();

    std::string S2;
    llvm::raw_string_ostream O2(S2);
    getCXXABI().getMangleContext().mangleTypeName(
        QualType(E2.first->getTypeForDecl(), 0), O2);
    O2.flush();

    if (S1 < S2)
      return true;
    if (S1 != S2)
      return false;

    return E1.second < E2.second;
  });

  for (auto BitsetEntry : BitsetEntries)
    AddVTableTypeMetadata(VTable, PointerWidth * BitsetEntry.second,
                          BitsetEntry.first);
}
Пример #3
0
void CodeGenModule::EmitVTableTypeMetadata(llvm::GlobalVariable *VTable,
                                           const VTableLayout &VTLayout) {
  if (!getCodeGenOpts().LTOUnit)
    return;

  CharUnits PointerWidth =
      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));

  typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
  std::vector<AddressPoint> AddressPoints;
  for (auto &&AP : VTLayout.getAddressPoints())
    AddressPoints.push_back(std::make_pair(
        AP.first.getBase(), VTLayout.getVTableOffset(AP.second.VTableIndex) +
                                AP.second.AddressPointIndex));

  // Sort the address points for determinism.
  llvm::sort(AddressPoints, [this](const AddressPoint &AP1,
                                   const AddressPoint &AP2) {
    if (&AP1 == &AP2)
      return false;

    std::string S1;
    llvm::raw_string_ostream O1(S1);
    getCXXABI().getMangleContext().mangleTypeName(
        QualType(AP1.first->getTypeForDecl(), 0), O1);
    O1.flush();

    std::string S2;
    llvm::raw_string_ostream O2(S2);
    getCXXABI().getMangleContext().mangleTypeName(
        QualType(AP2.first->getTypeForDecl(), 0), O2);
    O2.flush();

    if (S1 < S2)
      return true;
    if (S1 != S2)
      return false;

    return AP1.second < AP2.second;
  });

  ArrayRef<VTableComponent> Comps = VTLayout.vtable_components();
  for (auto AP : AddressPoints) {
    // Create type metadata for the address point.
    AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first);

    // The class associated with each address point could also potentially be
    // used for indirect calls via a member function pointer, so we need to
    // annotate the address of each function pointer with the appropriate member
    // function pointer type.
    for (unsigned I = 0; I != Comps.size(); ++I) {
      if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer)
        continue;
      llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
          Context.getMemberPointerType(
              Comps[I].getFunctionDecl()->getType(),
              Context.getRecordType(AP.first).getTypePtr()));
      VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
    }
  }
}