Skip to content

Commit 744806a

Browse files
committed
[Reflection] Add Foreign, ObjC, and Opaque type references
These likely don't have Swift type metadata but might be useful to record or instantiate based on what kind of metadata is encountered for the sake of memory tools.
1 parent 570e1ce commit 744806a

File tree

13 files changed

+1051
-2
lines changed

13 files changed

+1051
-2
lines changed

include/swift/Reflection/Records.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,47 @@
2222
namespace swift {
2323
namespace reflection {
2424

25+
class FieldRecordFlags {
26+
using int_type = uint32_t;
27+
enum : int_type {
28+
IsObjC = 0x00000001,
29+
};
30+
int_type Data;
31+
public:
32+
bool isObjC() const {
33+
return Data & IsObjC;
34+
}
35+
36+
void setIsObjC(bool ObjC) {
37+
if (ObjC)
38+
Data |= IsObjC;
39+
else
40+
Data &= ~IsObjC;
41+
}
42+
43+
int_type getRawValue() const {
44+
return Data;
45+
}
46+
};
47+
2548
class FieldRecord {
49+
const FieldRecordFlags Flags;
2650
const RelativeDirectPointer<const char> MangledTypeName;
2751
const RelativeDirectPointer<const char> FieldName;
2852

2953
public:
54+
FieldRecord() = delete;
3055
std::string getMangledTypeName() const {
3156
return MangledTypeName.get();
3257
}
3358

3459
std::string getFieldName() const {
3560
return FieldName.get();
3661
}
62+
63+
bool isObjC() const {
64+
return Flags.isObjC();
65+
}
3766
};
3867

3968
struct FieldRecordIterator {

include/swift/Reflection/ReflectionContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- ReflectionContext.h - Swift Type Reflection Context ----*- C++ -*-===//
1+
//===--- ReflectionContext.h - Swift Type Reflection Context ----*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//

include/swift/Reflection/TypeRef.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,47 @@ class AssociatedTypeRef final : public TypeRef {
366366
}
367367
};
368368

369+
class ForeignClassTypeRef final : public TypeRef {
370+
std::string Name;
371+
public:
372+
ForeignClassTypeRef(std::string Name)
373+
: TypeRef(TypeRefKind::ForeignClass), Name(Name) {}
374+
static const std::shared_ptr<ForeignClassTypeRef> Unnamed;
375+
376+
std::string getName() const {
377+
return Name;
378+
}
379+
380+
static bool classof(const TypeRef *TR) {
381+
return TR->getKind() == TypeRefKind::ForeignClass;
382+
}
383+
};
384+
385+
class ObjCClassTypeRef final : public TypeRef {
386+
std::string Name;
387+
public:
388+
ObjCClassTypeRef(std::string Name)
389+
: TypeRef(TypeRefKind::ObjCClass), Name(Name) {}
390+
static const std::shared_ptr<ObjCClassTypeRef> Unnamed;
391+
392+
std::string getName() const {
393+
return Name;
394+
}
395+
396+
static bool classof(const TypeRef *TR) {
397+
return TR->getKind() == TypeRefKind::ObjCClass;
398+
}
399+
};
400+
401+
class OpaqueTypeRef final : public TypeRef {
402+
public:
403+
OpaqueTypeRef() : TypeRef(TypeRefKind::Opaque) {}
404+
static const std::shared_ptr<OpaqueTypeRef> Opaque;
405+
static bool classof(const TypeRef *TR) {
406+
return TR->getKind() == TypeRefKind::Opaque;
407+
}
408+
};
409+
369410
template <typename ImplClass, typename RetTy = void, typename... Args>
370411
class TypeRefVisitor {
371412
public:
@@ -504,6 +545,23 @@ class PrintTypeRef : public TypeRefVisitor<PrintTypeRef, void> {
504545
printField("name", AT->getName());
505546
OS << ')';
506547
}
548+
549+
void visitForeignClassTypeRef(const ForeignClassTypeRef *F) {
550+
printHeader("foreign");
551+
printField("name", F->getName());
552+
OS << ')';
553+
}
554+
555+
void visitObjCClassTypeRef(const ObjCClassTypeRef *OC) {
556+
printHeader("objective-c-class");
557+
printField("name", OC->getName());
558+
OS << ')';
559+
}
560+
561+
void visitOpaqueTypeRef(const OpaqueTypeRef *O) {
562+
printHeader("opaque");
563+
OS << ')';
564+
}
507565
};
508566

509567
TypeRefPointer decodeDemangleNode(Demangle::NodePointer Node) {

include/swift/Reflection/TypeRefs.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ TYPEREF(ExistentialMetatype, TypeRef)
2828
TYPEREF(GenericTypeParameter, TypeRef)
2929
TYPEREF(DependentMember, TypeRef)
3030
TYPEREF(Associated, TypeRef)
31+
TYPEREF(ForeignClass, TypeRef)
32+
TYPEREF(ObjCClass, TypeRef)
33+
TYPEREF(Opaque, TypeRef)
3134

3235
#undef TYPEREF

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_subdirectory(Markup)
1212
add_subdirectory(Option)
1313
add_subdirectory(Parse)
1414
add_subdirectory(PrintAsObjC)
15+
add_subdirectory(Reflection)
1516
add_subdirectory(Sema)
1617
add_subdirectory(Serialization)
1718
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")

lib/IRGen/GenReflection.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/Decl.h"
1919
#include "swift/AST/IRGenOptions.h"
2020
#include "swift/AST/ProtocolConformance.h"
21+
#include "swift/Reflection/Records.h"
2122

2223
#include "ConstantBuilder.h"
2324
#include "IRGenModule.h"
@@ -120,10 +121,15 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
120121

121122
class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
122123

123-
const uint32_t fieldRecordSize = 8;
124+
const uint32_t fieldRecordSize = 12;
124125
ArrayRef<const NominalTypeDecl *> NominalTypeDecls;
125126

126127
void addFieldDecl(const ValueDecl *value) {
128+
swift::reflection::FieldRecordFlags Flags;
129+
Flags.setIsObjC(value->isObjC());
130+
131+
addConstantInt32(Flags.getRawValue());
132+
127133
auto type = value->getInterfaceType()->getCanonicalType();
128134
addTypeRef(value->getModuleContext(), type);
129135

lib/Reflection/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
add_swift_library(swiftReflection
2+
TypeRef.cpp)

lib/Reflection/TypeRef.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===--- TypeRef.h - Swift Type References for Reflection -------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Implements the structures of type references for property and enum
14+
// case reflection.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#include "swift/Reflection/TypeRef.h"
19+
20+
using namespace swift;
21+
using namespace reflection;
22+
23+
const std::shared_ptr<ForeignClassTypeRef>
24+
ForeignClassTypeRef::Unnamed = std::make_shared<ForeignClassTypeRef>("");
25+
26+
const std::shared_ptr<ObjCClassTypeRef>
27+
ObjCClassTypeRef::Unnamed = std::make_shared<ObjCClassTypeRef>("");
28+
29+
const std::shared_ptr<OpaqueTypeRef>
30+
OpaqueTypeRef::Opaque = std::make_shared<OpaqueTypeRef>();

test/Reflection/Inputs/ConcreteTypes.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#if _runtime(_ObjC)
2+
import Foundation
3+
#endif
4+
15
public class Box<Treasure> {
26
public let item: Treasure
37
public init(item: Treasure) {
@@ -40,3 +44,30 @@ public enum E {
4044
indirect case IndirectTuple(C, S, E, Int)
4145
case Metatype(E.Type)
4246
}
47+
48+
#if _runtime(_ObjC)
49+
50+
public class OC : NSObject {
51+
public let aClass: C
52+
public let aStruct: S
53+
public let anEnum: E
54+
public let aTuple: (C, S, E, Int)
55+
public let aMetatype: C.Type
56+
public let aFunction: (C, S, E, Int) -> (Int)
57+
public let nsObject: NSObject
58+
public let nsString: NSString
59+
public let cfString: CFString
60+
public init(aClass: C, aStruct: S, anEnum: E, aTuple: (C, S, E, Int), aMetatype: C.Type, aFunction: (C, S, E, Int) -> Int, nsObject: NSObject, nsString: NSString, cfString: CFString) {
61+
self.aClass = aClass
62+
self.aStruct = aStruct
63+
self.anEnum = anEnum
64+
self.aTuple = aTuple
65+
self.aMetatype = aMetatype
66+
self.aFunction = aFunction
67+
self.nsObject = nsObject
68+
self.nsString = nsString
69+
self.cfString = cfString
70+
}
71+
}
72+
73+
#endif

test/Reflection/Inputs/GenericTypes.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#if _runtime(_ObjC)
2+
import Foundation
3+
#endif
4+
15
public class C1<T> : ClassBoundP {
26
public typealias Function = C1<T> -> S1<T> -> E1<T> -> Int
37
public typealias Tuple = (C1<T>, S1<T>, E1<T>, Int)
@@ -158,3 +162,16 @@ extension E4 : P1, P2, P3 {
158162
public typealias Outer = U
159163
public typealias Second = U
160164
}
165+
166+
#if _runtime(_ObjC)
167+
168+
public class GenericOC<T> : NSObject {
169+
public let ocnss: GenericOC<NSString>
170+
public let occfs: GenericOC<CFString>
171+
public init(nss: GenericOC<NSString>, cfs: GenericOC<CFString>) {
172+
self.ocnss = nss
173+
self.occfs = cfs
174+
}
175+
}
176+
177+
#endif

test/Reflection/typeref_decoding.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
// RUN: %target-swiftc_driver %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift -emit-module -emit-library -module-name TypesToReflect -Xfrontend -enable-reflection-metadata -o %t/libTypesToReflect
33
// RUN: %target-swift-reflection-test -binary-filename %t/libTypesToReflect -dump-reflection-sections > %t/typeref_decoding.txt
44
// RUN: diff -u %S/typeref_decoding.result.txt %t/typeref_decoding.txt
5+
// UNSUPPORTED: objc_interop

0 commit comments

Comments
 (0)