예제 #1
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;
    }
  }
예제 #2
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;
    }
  }
예제 #3
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;
    }
  }