Skip to content

Commit 4c67ec0

Browse files
Merge pull request swiftlang#9712 from swiftlang/api-notes-swift-returns-retained-apple-upstream-llvm-fork-swift/release/6.1
🍒 [APINotes] Add SWIFT_RETURNS_(UN)RETAINED support to APINotes
2 parents 1d2d379 + b384963 commit 4c67ec0

File tree

10 files changed

+87
-3
lines changed

10 files changed

+87
-3
lines changed

clang/include/clang/APINotes/Types.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,9 @@ class FunctionInfo : public CommonEntityInfo {
542542
/// The result type of this function, as a C type.
543543
std::string ResultType;
544544

545+
/// Ownership convention for return value
546+
std::string SwiftReturnOwnership;
547+
545548
/// The function parameters.
546549
std::vector<ParamInfo> Params;
547550

@@ -622,7 +625,8 @@ inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
622625
LHS.NumAdjustedNullable == RHS.NumAdjustedNullable &&
623626
LHS.NullabilityPayload == RHS.NullabilityPayload &&
624627
LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params &&
625-
LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
628+
LHS.RawRetainCountConvention == RHS.RawRetainCountConvention &&
629+
LHS.SwiftReturnOwnership == RHS.SwiftReturnOwnership;
626630
}
627631

628632
inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {

clang/lib/APINotes/APINotesFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
2424
/// API notes file minor version number.
2525
///
2626
/// When the format changes IN ANY WAY, this number should be incremented.
27-
const uint16_t VERSION_MINOR = 33; // SwiftEscapable
27+
const uint16_t VERSION_MINOR = 34; // SwiftReturnOwnership
2828

2929
const uint8_t kSwiftConforms = 1;
3030
const uint8_t kSwiftDoesNotConform = 2;

clang/lib/APINotes/APINotesReader.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,13 @@ void ReadFunctionInfo(const uint8_t *&Data, FunctionInfo &Info) {
373373
endian::readNext<uint16_t, llvm::endianness::little>(Data);
374374
Info.ResultType = std::string(Data, Data + ResultTypeLen);
375375
Data += ResultTypeLen;
376+
377+
unsigned SwiftReturnOwnershipLength =
378+
endian::readNext<uint16_t, llvm::endianness::little>(Data);
379+
Info.SwiftReturnOwnership = std::string(reinterpret_cast<const char *>(Data),
380+
reinterpret_cast<const char *>(Data) +
381+
SwiftReturnOwnershipLength);
382+
Data += SwiftReturnOwnershipLength;
376383
}
377384

378385
/// Used to deserialize the on-disk Objective-C method table.

clang/lib/APINotes/APINotesTypes.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ LLVM_DUMP_METHOD void FunctionInfo::dump(llvm::raw_ostream &OS) const {
7777
<< "RawRetainCountConvention: " << RawRetainCountConvention << ' ';
7878
if (!ResultType.empty())
7979
OS << "Result Type: " << ResultType << ' ';
80+
if (!SwiftReturnOwnership.empty())
81+
OS << "SwiftReturnOwnership: " << SwiftReturnOwnership << ' ';
8082
if (!Params.empty())
8183
OS << '\n';
8284
for (auto &PI : Params)

clang/lib/APINotes/APINotesWriter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ unsigned getFunctionInfoSize(const FunctionInfo &FI) {
11101110
for (const auto &P : FI.Params)
11111111
size += getParamInfoSize(P);
11121112
size += sizeof(uint16_t) + FI.ResultType.size();
1113+
size += sizeof(uint16_t) + FI.SwiftReturnOwnership.size();
11131114
return size;
11141115
}
11151116

@@ -1135,6 +1136,9 @@ void emitFunctionInfo(raw_ostream &OS, const FunctionInfo &FI) {
11351136

11361137
writer.write<uint16_t>(FI.ResultType.size());
11371138
writer.write(ArrayRef<char>{FI.ResultType.data(), FI.ResultType.size()});
1139+
writer.write<uint16_t>(FI.SwiftReturnOwnership.size());
1140+
writer.write(ArrayRef<char>{FI.SwiftReturnOwnership.data(),
1141+
FI.SwiftReturnOwnership.size()});
11381142
}
11391143

11401144
/// Used to serialize the on-disk global function table.

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ struct Method {
275275
bool DesignatedInit = false;
276276
bool Required = false;
277277
StringRef ResultType;
278+
StringRef SwiftReturnOwnership;
278279
};
279280

280281
typedef std::vector<Method> MethodsSeq;
@@ -309,6 +310,8 @@ template <> struct MappingTraits<Method> {
309310
IO.mapOptional("DesignatedInit", M.DesignatedInit, false);
310311
IO.mapOptional("Required", M.Required, false);
311312
IO.mapOptional("ResultType", M.ResultType, StringRef(""));
313+
IO.mapOptional("SwiftReturnOwnership", M.SwiftReturnOwnership,
314+
StringRef(""));
312315
}
313316
};
314317
} // namespace yaml
@@ -404,6 +407,7 @@ struct Function {
404407
StringRef SwiftName;
405408
StringRef Type;
406409
StringRef ResultType;
410+
StringRef SwiftReturnOwnership;
407411
};
408412

409413
typedef std::vector<Function> FunctionsSeq;
@@ -426,6 +430,8 @@ template <> struct MappingTraits<Function> {
426430
IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
427431
IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
428432
IO.mapOptional("ResultType", F.ResultType, StringRef(""));
433+
IO.mapOptional("SwiftReturnOwnership", F.SwiftReturnOwnership,
434+
StringRef(""));
429435
}
430436
};
431437
} // namespace yaml
@@ -938,6 +944,7 @@ class YAMLConverter {
938944
emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead");
939945

940946
MI.ResultType = std::string(M.ResultType);
947+
MI.SwiftReturnOwnership = std::string(M.SwiftReturnOwnership);
941948

942949
// Translate parameter information.
943950
convertParams(M.Params, MI, MI.Self);
@@ -1063,6 +1070,7 @@ class YAMLConverter {
10631070
convertNullability(Function.Nullability, Function.NullabilityOfRet, FI,
10641071
Function.Name);
10651072
FI.ResultType = std::string(Function.ResultType);
1073+
FI.SwiftReturnOwnership = std::string(Function.SwiftReturnOwnership);
10661074
FI.setRetainCountConvention(Function.RetainCountConvention);
10671075
}
10681076

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,11 @@ static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc,
512512
AnyTypeChanged = true;
513513
}
514514

515+
// returns_(un)retained
516+
if (!Info.SwiftReturnOwnership.empty())
517+
D->addAttr(SwiftAttrAttr::Create(S.Context,
518+
"returns_" + Info.SwiftReturnOwnership));
519+
515520
// Result type override.
516521
QualType OverriddenResultType;
517522
if (Metadata.IsActive && !Info.ResultType.empty() &&

clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ Name: SwiftImportAs
33
Tags:
44
- Name: ImmortalRefType
55
SwiftImportAs: reference
6+
Methods:
7+
- Name: methodReturningFrt__
8+
- Name: methodReturningFrt_returns_unretained
9+
SwiftReturnOwnership: unretained
10+
- Name: methodReturningFrt_returns_retained
11+
SwiftReturnOwnership: retained
612
- Name: RefCountedType
713
SwiftImportAs: reference
814
SwiftReleaseOp: RCRelease
@@ -17,3 +23,10 @@ Tags:
1723
SwiftEscapable: false
1824
- Name: EscapableType
1925
SwiftEscapable: true
26+
27+
Functions:
28+
- Name: functionReturningFrt__
29+
- Name: functionReturningFrt_returns_unretained
30+
SwiftReturnOwnership: unretained
31+
- Name: functionReturningFrt_returns_retained
32+
SwiftReturnOwnership: retained

clang/test/APINotes/Inputs/Headers/SwiftImportAs.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
struct ImmortalRefType {};
1+
struct ImmortalRefType {
2+
ImmortalRefType * methodReturningFrt__(void);
3+
ImmortalRefType * methodReturningFrt_returns_unretained(void);
4+
ImmortalRefType * methodReturningFrt_returns_retained(void);
5+
};
6+
7+
ImmortalRefType * functionReturningFrt__(void);
8+
ImmortalRefType * functionReturningFrt_returns_unretained(void);
9+
ImmortalRefType * functionReturningFrt_returns_retained(void);
10+
211

312
struct RefCountedType { int value; };
413

clang/test/APINotes/swift-import-as.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter CopyableType | FileCheck -check-prefix=CHECK-COPYABLE %s
77
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter NonEscapableType | FileCheck -check-prefix=CHECK-NON-ESCAPABLE %s
88
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter EscapableType | FileCheck -check-prefix=CHECK-ESCAPABLE %s
9+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter functionReturningFrt__ | FileCheck -check-prefix=CHECK-FUNCTION-RETURNING-FRT %s
10+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter functionReturningFrt_returns_unretained | FileCheck -check-prefix=CHECK-FUNCTION-RETURNING-FRT-UNRETAINED %s
11+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter functionReturningFrt_returns_retained | FileCheck -check-prefix=CHECK-FUNCTION-RETURNING-FRT-RETAINED %s
12+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt__ | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT %s
13+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt_returns_unretained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-UNRETAINED %s
14+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt_returns_retained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-RETAINED %s
915

1016
#include <SwiftImportAs.h>
1117

@@ -36,3 +42,29 @@
3642
// CHECK-ESCAPABLE: Dumping EscapableType:
3743
// CHECK-ESCAPABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct EscapableType
3844
// CHECK-ESCAPABLE: SwiftAttrAttr {{.+}} "Escapable"
45+
46+
// CHECK-FUNCTION-RETURNING-FRT: Dumping functionReturningFrt__:
47+
// CHECK-FUNCTION-RETURNING-FRT: FunctionDecl {{.+}} imported in SwiftImportAs functionReturningFrt__ 'ImmortalRefType *()'
48+
// CHECK-FUNCTION-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_unretained"
49+
// CHECK-FUNCTION-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_retained"
50+
51+
// CHECK-FUNCTION-RETURNING-FRT-UNRETAINED: Dumping functionReturningFrt_returns_unretained:
52+
// CHECK-FUNCTION-RETURNING-FRT-UNRETAINED: FunctionDecl {{.+}} imported in SwiftImportAs functionReturningFrt_returns_unretained 'ImmortalRefType *()'
53+
// CHECK-FUNCTION-RETURNING-FRT-UNRETAINED: `-SwiftAttrAttr {{.+}} "returns_unretained"
54+
55+
// CHECK-FUNCTION-RETURNING-FRT-RETAINED: Dumping functionReturningFrt_returns_retained:
56+
// CHECK-FUNCTION-RETURNING-FRT-RETAINED: FunctionDecl {{.+}} imported in SwiftImportAs functionReturningFrt_returns_retained 'ImmortalRefType *()'
57+
// CHECK-FUNCTION-RETURNING-FRT-RETAINED: `-SwiftAttrAttr {{.+}} "returns_retained"
58+
59+
// CHECK-METHOD-RETURNING-FRT: Dumping ImmortalRefType::methodReturningFrt__:
60+
// CHECK-METHOD-RETURNING-FRT: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt__ 'ImmortalRefType *()'
61+
// CHECK-METHOD-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_unretained"
62+
// CHECK-METHOD-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_retained"
63+
64+
// CHECK-METHOD-RETURNING-FRT-UNRETAINED: Dumping ImmortalRefType::methodReturningFrt_returns_unretained:
65+
// CHECK-METHOD-RETURNING-FRT-UNRETAINED: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt_returns_unretained 'ImmortalRefType *()'
66+
// CHECK-METHOD-RETURNING-FRT-UNRETAINED: `-SwiftAttrAttr {{.+}} "returns_unretained"
67+
68+
// CHECK-METHOD-RETURNING-FRT-RETAINED: Dumping ImmortalRefType::methodReturningFrt_returns_retained:
69+
// CHECK-METHOD-RETURNING-FRT-RETAINED: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt_returns_retained 'ImmortalRefType *()'
70+
// CHECK-METHOD-RETURNING-FRT-RETAINED: `-SwiftAttrAttr {{.+}} "returns_retained"

0 commit comments

Comments
 (0)