예제 #1
0
static Type findBaseTypeForReplacingArchetype(const ValueDecl *VD, const Type Ty) {
  if (Ty.isNull())
    return Type();

  // Find the nominal type decl related to VD.
  auto TC = VD->getDeclContext()->getInnermostTypeContext();
  NominalTypeDecl *NTD = dyn_cast_or_null<NominalTypeDecl>(TC);
  if (!NTD) {
    ExtensionDecl *ED = dyn_cast_or_null<ExtensionDecl>(TC);
    if (ED) {
      if (auto T = ED->getExtendedType())
        NTD = T->getAnyNominal();
    }
  }
  if (!NTD)
    return Type();
  Type Result;

  // Walk the type tree to find the a sub-type who's convertible to the
  // found nominal.
  Ty.visit([&](Type T) {
    if (!Result && (T->getAnyNominal() == NTD ||
                    isConvertibleTo(T, NTD->getDeclaredType(),
                                    VD->getDeclContext()))) {
      Result = T;
    }
  });
  return Result;
}
예제 #2
0
  void layout() override {
    PrettyStackTraceDecl DebugStack("emitting field type metadata", NTD);
    auto type = NTD->getDeclaredType()->getCanonicalType();
    addTypeRef(NTD->getModuleContext(), type);

    if (NTD->hasClangNode() &&
        !isa<ClassDecl>(NTD) &&
        !isa<ProtocolDecl>(NTD))
      return;

    switch (NTD->getKind()) {
      case DeclKind::Class:
      case DeclKind::Struct:
        layoutRecord();
        break;

      case DeclKind::Enum:
        layoutEnum();
        break;

      case DeclKind::Protocol:
        layoutProtocol();
        break;

      default:
        llvm_unreachable("Not a nominal type");
        break;
    }
  }
예제 #3
0
  void layout() {
    using swift::reflection::FieldDescriptorKind;

    PrettyStackTraceDecl DebugStack("emitting field type metadata", NTD);
    auto type = NTD->getDeclaredType()->getCanonicalType();
    addTypeRef(NTD->getModuleContext(), type);

    switch (NTD->getKind()) {
      case DeclKind::Class:
      case DeclKind::Struct: {
        auto properties = NTD->getStoredProperties();
        addConstantInt16(uint16_t(isa<StructDecl>(NTD)
                                  ? FieldDescriptorKind::Struct
                                  : FieldDescriptorKind::Class));
        addConstantInt16(fieldRecordSize);
        addConstantInt32(std::distance(properties.begin(), properties.end()));
        for (auto property : properties)
          addFieldDecl(property,
                       property->getInterfaceType()
                       ->getCanonicalType());
        break;
      }
      case DeclKind::Enum: {
        auto enumDecl = cast<EnumDecl>(NTD);
        auto cases = enumDecl->getAllElements();
        addConstantInt16(uint16_t(FieldDescriptorKind::Enum));
        addConstantInt16(fieldRecordSize);
        addConstantInt32(std::distance(cases.begin(), cases.end()));
        for (auto enumCase : cases) {
          if (enumCase->hasArgumentType()) {
            addFieldDecl(enumCase,
                         enumCase->getArgumentInterfaceType()
                         ->getCanonicalType());
          } else {
            addFieldDecl(enumCase, CanType());
          }
        }
        break;
      }
      case DeclKind::Protocol: {
        auto protocolDecl = cast<ProtocolDecl>(NTD);
        FieldDescriptorKind Kind;
        if (protocolDecl->isObjC())
          Kind = FieldDescriptorKind::ObjCProtocol;
        else if (protocolDecl->requiresClass())
          Kind = FieldDescriptorKind::ClassProtocol;
        else
          Kind = FieldDescriptorKind::Protocol;
        addConstantInt16(uint16_t(Kind));
        addConstantInt16(fieldRecordSize);
        addConstantInt32(0);
        break;
      }
      default:
        llvm_unreachable("Not a nominal type");
        break;
    }
  }
예제 #4
0
static Type findBaseTypeForReplacingArchetype(const ValueDecl *VD, const Type Ty) {
  if (Ty.isNull())
    return Type();

  // Find the nominal type decl related to VD.
  NominalTypeDecl *NTD = VD->getDeclContext()->
    getAsNominalTypeOrNominalTypeExtensionContext();
  if (!NTD)
    return Type();
  Type Result;

  // Walk the type tree to find the a sub-type who's convertible to the
  // found nominal.
  Ty.visit([&](Type T) {
    if (!Result && (T->getAnyNominal() == NTD ||
                    isConvertibleTo(T, NTD->getDeclaredType(),
                                    VD->getDeclContext()))) {
      Result = T;
    }
  });
  return Result;
}
예제 #5
0
  void layout() {
    using swift::reflection::FieldDescriptorKind;

    PrettyStackTraceDecl DebugStack("emitting field type metadata", NTD);
    auto type = NTD->getDeclaredType()->getCanonicalType();
    addTypeRef(NTD->getModuleContext(), type);

    if (NTD->hasClangNode() &&
        !isa<ClassDecl>(NTD) &&
        !isa<ProtocolDecl>(NTD))
      return;

    switch (NTD->getKind()) {
      case DeclKind::Class:
      case DeclKind::Struct: {
        auto kind = FieldDescriptorKind::Struct;

        if (auto CD = dyn_cast<ClassDecl>(NTD)) {
          auto RC = getReferenceCountingForClass(IGM, const_cast<ClassDecl *>(CD));
          if (RC == ReferenceCounting::ObjC)
            kind = FieldDescriptorKind::ObjCClass;
          else
            kind = FieldDescriptorKind::Class;
        }

        addConstantInt16(uint16_t(kind));
        addConstantInt16(fieldRecordSize);

        // Imported classes don't need field descriptors
        if (NTD->hasClangNode()) {
          assert(isa<ClassDecl>(NTD));
          addConstantInt32(0);
          break;
        }

        auto properties = NTD->getStoredProperties();
        addConstantInt32(std::distance(properties.begin(), properties.end()));
        for (auto property : properties)
          addFieldDecl(property,
                       property->getInterfaceType()
                       ->getCanonicalType());
        break;
      }
      case DeclKind::Enum: {
        auto enumDecl = cast<EnumDecl>(NTD);
        auto cases = enumDecl->getAllElements();
        addConstantInt16(uint16_t(FieldDescriptorKind::Enum));
        addConstantInt16(fieldRecordSize);
        addConstantInt32(std::distance(cases.begin(), cases.end()));
        for (auto enumCase : cases) {
          if (enumCase->hasArgumentType()) {
            addFieldDecl(enumCase,
                         enumCase->getArgumentInterfaceType()
                         ->getCanonicalType());
          } else {
            addFieldDecl(enumCase, CanType());
          }
        }
        break;
      }
      case DeclKind::Protocol: {
        auto protocolDecl = cast<ProtocolDecl>(NTD);
        FieldDescriptorKind Kind;
        if (protocolDecl->isObjC())
          Kind = FieldDescriptorKind::ObjCProtocol;
        else if (protocolDecl->requiresClass())
          Kind = FieldDescriptorKind::ClassProtocol;
        else
          Kind = FieldDescriptorKind::Protocol;
        addConstantInt16(uint16_t(Kind));
        addConstantInt16(fieldRecordSize);
        addConstantInt32(0);
        break;
      }
      default:
        llvm_unreachable("Not a nominal type");
        break;
    }
  }
예제 #6
0
 llvm::GlobalVariable *emit() {
   auto entity = LinkEntity::forReflectionFieldDescriptor(
       NTD->getDeclaredType()->getCanonicalType());
   auto section = IGM.getFieldTypeMetadataSectionName();
   return ReflectionMetadataBuilder::emit(entity, section);
 }