void layoutRecord() { auto kind = FieldDescriptorKind::Struct; if (auto CD = dyn_cast<ClassDecl>(NTD)) { auto type = CD->getDeclaredType()->getCanonicalType(); auto RC = getReferenceCountingForType(IGM, type); if (RC == ReferenceCounting::ObjC) kind = FieldDescriptorKind::ObjCClass; else kind = FieldDescriptorKind::Class; } B.addInt16(uint16_t(kind)); B.addInt16(fieldRecordSize); // Imported classes don't need field descriptors if (NTD->hasClangNode() && isa<ClassDecl>(NTD)) { B.addInt32(0); return; } assert(!NTD->hasClangNode() || isa<StructDecl>(NTD)); auto properties = NTD->getStoredProperties(); B.addInt32(std::distance(properties.begin(), properties.end())); for (auto property : properties) addFieldDecl(property, property->getInterfaceType() ->getCanonicalType()); }
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; } }
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; } }
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; } }