Пример #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 findExtensionsFromConformingProtocols(Decl *D,
                                           llvm::SmallPtrSetImpl<ExtensionDecl*> &Results) {
  NominalTypeDecl* NTD = dyn_cast<NominalTypeDecl>(D);
  if (!NTD || NTD->getKind() == DeclKind::Protocol)
    return;
  std::vector<NominalTypeDecl*> Unhandled;
  auto addTypeLocNominal = [&](TypeLoc TL){
    if (TL.getType()) {
      if (auto D = TL.getType()->getAnyNominal()) {
        Unhandled.push_back(D);
      }
    }
  };
  for (auto TL : NTD->getInherited()) {
    addTypeLocNominal(TL);
  }
  while(!Unhandled.empty()) {
    NominalTypeDecl* Back = Unhandled.back();
    Unhandled.pop_back();
    for (ExtensionDecl *E : Back->getExtensions()) {
      if(E->isConstrainedExtension())
        Results.insert(E);
      for (auto TL : Back->getInherited()) {
        addTypeLocNominal(TL);
      }
    }
  }
}
Пример #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
  void layout() override {
    if (NTD->hasClangNode() &&
        !isa<ClassDecl>(NTD) &&
        !isa<StructDecl>(NTD) &&
        !isa<ProtocolDecl>(NTD))
      return;

    PrettyStackTraceDecl DebugStack("emitting field type metadata", NTD);
    addNominalRef(NTD);

    auto *CD = dyn_cast<ClassDecl>(NTD);
    if (CD && CD->getSuperclass()) {
      addTypeRef(CD->getSuperclass()->getCanonicalType());
    } else {
      B.addInt32(0);
    }

    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;
    }
  }
Пример #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;
    }
  }