Skip to content

Commit 3948a2a

Browse files
committed
[interop][SwiftToCxx] annotate inline thunks with SWIFT_INLINE_THUNK
This macro applies always_inline in addition to inline. It also applies artificial, which lets debugger know that this is an artificial function. The used attribute is added in debug builds to ensure that the symbol is emitted in the binary so that LLDB can invoke it.
1 parent 021f3a9 commit 3948a2a

File tree

59 files changed

+705
-628
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+705
-628
lines changed

include/swift/PrintAsClang/ClangMacros.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@ CLANG_MACRO_DEFINED("SWIFT_IMPORT_STDLIB_SYMBOL")
224224

225225
CLANG_MACRO_CXX("SWIFT_NOEXCEPT", , "noexcept", )
226226

227+
CLANG_MACRO_BODY("SWIFT_C_INLINE_THUNK", \
228+
"# if __has_attribute(always_inline)\n" \
229+
"# if __has_attribute(nodebug)\n" \
230+
"# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug))\n" \
231+
"# else\n" \
232+
"# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline))\n" \
233+
"# endif\n" \
234+
"# else\n" \
235+
"# define SWIFT_C_INLINE_THUNK inline\n"\
236+
"# endif")
237+
227238
#undef CLANG_MACRO
228239
#undef CLANG_MACRO_BODY
229240
#undef CLANG_MACRO_DEFINED

lib/PrintAsClang/ClangSyntaxPrinter.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,7 @@ void ClangSyntaxPrinter::printSwiftImplQualifier() const {
194194
}
195195

196196
void ClangSyntaxPrinter::printInlineForThunk() const {
197-
// FIXME: make a macro and add 'nodebug', and
198-
// migrate all other 'inline' uses.
199-
os << "inline __attribute__((always_inline)) ";
197+
os << "SWIFT_INLINE_THUNK ";
200198
}
201199

202200
void ClangSyntaxPrinter::printNullability(

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,15 @@ class DeclAndTypePrinter::Implementation
434434
ClangSyntaxPrinter(nameOS).printIdentifier(caseName);
435435
name[0] = std::toupper(name[0]);
436436

437-
os << " inline bool is" << name << "() const;\n";
437+
os << " ";
438+
ClangSyntaxPrinter(os).printInlineForThunk();
439+
os << "bool is" << name << "() const;\n";
438440

439441
outOfLineSyntaxPrinter
440442
.printNominalTypeOutsideMemberDeclTemplateSpecifiers(ED);
441-
outOfLineOS << " inline bool ";
443+
outOfLineOS << " ";
444+
ClangSyntaxPrinter(outOfLineOS).printInlineForThunk();
445+
outOfLineOS << " bool ";
442446
outOfLineSyntaxPrinter.printNominalTypeQualifier(
443447
ED, /*moduleContext=*/ED->getModuleContext());
444448
outOfLineOS << "is" << name << "() const {\n";
@@ -469,10 +473,14 @@ class DeclAndTypePrinter::Implementation
469473
/*NeedsReturnTypes=*/true,
470474
[&](auto &types) {
471475
// Printing function name and return type
472-
os << " inline " << types[paramType] << " get" << name;
476+
os << " ";
477+
ClangSyntaxPrinter(os).printInlineForThunk();
478+
os << types[paramType] << " get" << name;
473479
outOfLineSyntaxPrinter
474480
.printNominalTypeOutsideMemberDeclTemplateSpecifiers(ED);
475-
outOfLineOS << " inline " << types[paramType] << ' ';
481+
outOfLineOS << " ";
482+
ClangSyntaxPrinter(outOfLineOS).printInlineForThunk();
483+
outOfLineOS << types[paramType] << ' ';
476484
outOfLineSyntaxPrinter.printNominalTypeQualifier(
477485
ED, /*moduleContext=*/ED->getModuleContext());
478486
outOfLineOS << "get" << name;
@@ -550,7 +558,9 @@ class DeclAndTypePrinter::Implementation
550558
elementInfo) {
551559
os << " inline const static struct _impl_" << caseName << " { "
552560
<< "// impl struct for case " << caseName << '\n';
553-
os << " inline constexpr operator cases() const {\n";
561+
os << " ";
562+
syntaxPrinter.printInlineForThunk();
563+
os << "constexpr operator cases() const {\n";
554564
os << " return cases::";
555565
syntaxPrinter.printIdentifier(caseName);
556566
os << ";\n";
@@ -579,14 +589,15 @@ class DeclAndTypePrinter::Implementation
579589
[&](auto &types) {
580590
const auto *ED = elementDecl->getParentEnum();
581591
// Printing function name and return type
582-
os << " inline ";
592+
os << " SWIFT_INLINE_THUNK "; // TODO
583593
syntaxPrinter.printNominalTypeReference(ED,
584594
ED->getModuleContext());
585595
os << " operator()";
586596

587597
outOfLineSyntaxPrinter
588598
.printNominalTypeOutsideMemberDeclTemplateSpecifiers(ED);
589-
outOfLineOS << " inline ";
599+
outOfLineOS << " ";
600+
outOfLineSyntaxPrinter.printInlineForThunk();
590601
outOfLineSyntaxPrinter.printNominalTypeReference(
591602
ED, ED->getModuleContext());
592603
outOfLineOS << ' ';
@@ -794,7 +805,9 @@ class DeclAndTypePrinter::Implementation
794805
os << "#pragma clang diagnostic pop\n";
795806

796807
// Printing operator cases()
797-
os << " inline operator cases() const {\n";
808+
os << " ";
809+
ClangSyntaxPrinter(os).printInlineForThunk();
810+
os << "operator cases() const {\n";
798811
if (ED->isResilient()) {
799812
if (!elementTagMapping.empty()) {
800813
os << " auto tag = _getEnumTag();\n";

lib/PrintAsClang/PrintClangClassType.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ void ClangClassTypePrinter::printClassTypeDecl(
7070
os << " using " << baseClassName << "::operator=;\n";
7171
bodyPrinter();
7272
os << "protected:\n";
73-
os << " inline ";
73+
os << " ";
74+
printer.printInlineForThunk();
7475
printer.printBaseName(typeDecl);
7576
os << "(void * _Nonnull ptr) noexcept : " << baseClassName << "(ptr) {}\n";
7677
os << "private:\n";
@@ -86,7 +87,8 @@ void ClangClassTypePrinter::printClassTypeDecl(
8687
printCxxImplClassName(os, typeDecl);
8788
os << " {\n";
8889
os << "public:\n";
89-
os << "static inline ";
90+
os << "static ";
91+
printer.printInlineForThunk();
9092
printer.printBaseName(typeDecl);
9193
os << " makeRetained(void * _Nonnull ptr) noexcept { return ";
9294
printer.printBaseName(typeDecl);

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,10 @@ static void printDirectReturnOrParamCType(
610610
minimalStubName.consume_front(stubTypeName);
611611
if (isResultType) {
612612
// Emit a stub that returns a value directly from swiftcc function.
613-
os << "static inline void swift_interop_returnDirect_" << minimalStubName;
613+
os << "static SWIFT_C_INLINE_THUNK void swift_interop_returnDirect_"
614+
<< minimalStubName;
614615
os << "(char * _Nonnull result, struct " << stubName << " value";
615-
os << ") __attribute__((always_inline)) {\n";
616+
os << ") {\n";
616617
for (size_t i = 0; i < fields.size(); ++i) {
617618
os << " memcpy(result + " << fields[i].first.getQuantity() << ", "
618619
<< "&value._" << (i + 1) << ", "
@@ -621,9 +622,9 @@ static void printDirectReturnOrParamCType(
621622
} else {
622623
// Emit a stub that is used to pass value type directly to swiftcc
623624
// function.
624-
os << "static inline struct " << stubName << " swift_interop_passDirect_"
625-
<< minimalStubName;
626-
os << "(const char * _Nonnull value) __attribute__((always_inline)) {\n";
625+
os << "static SWIFT_C_INLINE_THUNK struct " << stubName
626+
<< " swift_interop_passDirect_" << minimalStubName;
627+
os << "(const char * _Nonnull value) {\n";
627628
os << " struct " << stubName << " result;\n";
628629
for (size_t i = 0; i < fields.size(); ++i) {
629630
os << " memcpy(&result._" << (i + 1) << ", value + "
@@ -710,7 +711,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
710711
os << "static ";
711712
}
712713
if (modifiers.isInline)
713-
os << "inline ";
714+
ClangSyntaxPrinter(os).printInlineForThunk();
714715

715716
ClangRepresentation resultingRepresentation =
716717
ClangRepresentation::representable;

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -117,20 +117,21 @@ static void addCppExtensionsToStdlibType(const NominalTypeDecl *typeDecl,
117117
"uint32_t _3;\n"
118118
"#endif\n"
119119
"};\n";
120-
cPrologueOS << "static inline struct swift_interop_stub_Swift_String "
121-
"swift_interop_passDirect_Swift_String(const char * "
122-
"_Nonnull value) {\n"
123-
"struct swift_interop_stub_Swift_String result;\n"
124-
"#if UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu\n"
125-
"memcpy(&result._1, value, 8);\n"
126-
"memcpy(&result._2, value + 8, 8);\n"
127-
"#elif UINTPTR_MAX == 0xFFFFFFFF\n"
128-
"memcpy(&result._1, value, 4);\n"
129-
"memcpy(&result._2, value + 4, 4);\n"
130-
"memcpy(&result._3, value + 8, 4);\n"
131-
"#endif\n"
132-
"return result;\n"
133-
"}\n";
120+
cPrologueOS
121+
<< "static SWIFT_INLINE_THUNK struct swift_interop_stub_Swift_String "
122+
"swift_interop_passDirect_Swift_String(const char * "
123+
"_Nonnull value) {\n"
124+
"struct swift_interop_stub_Swift_String result;\n"
125+
"#if UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu\n"
126+
"memcpy(&result._1, value, 8);\n"
127+
"memcpy(&result._2, value + 8, 8);\n"
128+
"#elif UINTPTR_MAX == 0xFFFFFFFF\n"
129+
"memcpy(&result._1, value, 4);\n"
130+
"memcpy(&result._2, value + 4, 4);\n"
131+
"memcpy(&result._3, value + 8, 4);\n"
132+
"#endif\n"
133+
"return result;\n"
134+
"}\n";
134135
cPrologueOS << "SWIFT_EXTERN void *_Nonnull "
135136
"$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(swift_interop_stub_"
136137
"Swift_String) SWIFT_NOEXCEPT SWIFT_CALL;\n";
@@ -272,15 +273,18 @@ void ClangValueTypePrinter::printValueTypeDecl(
272273
*genericSignature);
273274

274275
// Print out the destructor.
275-
os << " inline ~";
276+
os << " ";
277+
printer.printInlineForThunk();
278+
os << '~';
276279
printer.printBaseName(typeDecl);
277280
os << "() {\n";
278281
ClangValueTypePrinter::printValueWitnessTableAccessAsVariable(
279282
os, typeMetadataFuncName, typeMetadataFuncGenericParams);
280283
os << " vwTable->destroy(_getOpaquePointer(), metadata._0);\n";
281284
os << " }\n";
282285

283-
os << " inline ";
286+
os << " ";
287+
printer.printInlineForThunk();
284288
printer.printBaseName(typeDecl);
285289
os << "(const ";
286290
printer.printBaseName(typeDecl);
@@ -298,7 +302,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
298302
os << " }\n";
299303

300304
// FIXME: implement the move constructor.
301-
os << " [[noreturn]] inline ";
305+
os << " [[noreturn]] ";
306+
printer.printInlineForThunk();
302307
printer.printBaseName(typeDecl);
303308
os << "(";
304309
printer.printBaseName(typeDecl);
@@ -311,7 +316,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
311316
os << "private:\n";
312317

313318
// Print out private default constructor.
314-
os << " inline ";
319+
os << " ";
320+
printer.printInlineForThunk();
315321
printer.printBaseName(typeDecl);
316322
// FIXME: make noexcept.
317323
if (isOpaqueLayout) {
@@ -324,7 +330,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
324330
}
325331
// Print out '_make' function which returns an unitialized instance for
326332
// passing to Swift.
327-
os << " static inline ";
333+
os << " static ";
334+
printer.printInlineForThunk();
328335
printer.printBaseName(typeDecl);
329336
os << " _make() {";
330337
if (isOpaqueLayout) {
@@ -340,30 +347,40 @@ void ClangValueTypePrinter::printValueTypeDecl(
340347
os << "(); }\n";
341348
}
342349
// Print out the private accessors to the underlying Swift value storage.
343-
os << " inline const char * _Nonnull _getOpaquePointer() const { return "
350+
os << " ";
351+
printer.printInlineForThunk();
352+
os << "const char * _Nonnull _getOpaquePointer() const { return "
344353
"_storage";
345354
if (isOpaqueLayout)
346355
os << ".getOpaquePointer()";
347356
os << "; }\n";
348-
os << " inline char * _Nonnull _getOpaquePointer() { return _storage";
357+
os << " ";
358+
printer.printInlineForThunk();
359+
os << "char * _Nonnull _getOpaquePointer() { return _storage";
349360
if (isOpaqueLayout)
350361
os << ".getOpaquePointer()";
351362
os << "; }\n";
352363
os << "\n";
353364
// Print out helper function for enums
354365
if (isa<EnumDecl>(typeDecl)) {
355-
os << " inline char * _Nonnull _destructiveProjectEnumData() {\n";
366+
os << " ";
367+
printer.printInlineForThunk();
368+
os << "char * _Nonnull _destructiveProjectEnumData() {\n";
356369
printEnumVWTableVariable();
357370
os << " enumVWTable->destructiveProjectEnumData(_getOpaquePointer(), "
358371
"metadata._0);\n";
359372
os << " return _getOpaquePointer();\n";
360373
os << " }\n";
361-
os << " inline void _destructiveInjectEnumTag(unsigned tag) {\n";
374+
os << " ";
375+
printer.printInlineForThunk();
376+
os << "void _destructiveInjectEnumTag(unsigned tag) {\n";
362377
printEnumVWTableVariable();
363378
os << " enumVWTable->destructiveInjectEnumTag(_getOpaquePointer(), tag, "
364379
"metadata._0);\n";
365380
os << " }\n";
366-
os << " inline unsigned _getEnumTag() const {\n";
381+
os << " ";
382+
printer.printInlineForThunk();
383+
os << "unsigned _getEnumTag() const {\n";
367384
printEnumVWTableVariable();
368385
os << " return enumVWTable->getEnumTag(_getOpaquePointer(), "
369386
"metadata._0);\n";
@@ -399,18 +416,23 @@ void ClangValueTypePrinter::printValueTypeDecl(
399416
ClangSyntaxPrinter(os).printGenericSignatureInnerStaticAsserts(
400417
*genericSignature);
401418

402-
os << " static inline char * _Nonnull getOpaquePointer(";
419+
os << " static ";
420+
ClangSyntaxPrinter(os).printInlineForThunk();
421+
os << "char * _Nonnull getOpaquePointer(";
403422
printCxxTypeName(os, typeDecl, moduleContext);
404423
printGenericParamRefs(os);
405424
os << " &object) { return object._getOpaquePointer(); }\n";
406425

407-
os << " static inline const char * _Nonnull getOpaquePointer(const ";
426+
os << " static ";
427+
ClangSyntaxPrinter(os).printInlineForThunk();
428+
os << "const char * _Nonnull getOpaquePointer(const ";
408429
printCxxTypeName(os, typeDecl, moduleContext);
409430
printGenericParamRefs(os);
410431
os << " &object) { return object._getOpaquePointer(); }\n";
411432

412433
os << " template<class T>\n";
413-
os << " static inline ";
434+
os << " static ";
435+
ClangSyntaxPrinter(os).printInlineForThunk();
414436
printCxxTypeName(os, typeDecl, moduleContext);
415437
printGenericParamRefs(os);
416438
os << " returnNewValue(T callable) {\n";
@@ -422,7 +444,9 @@ void ClangValueTypePrinter::printValueTypeDecl(
422444
os << " return result;\n";
423445
os << " }\n";
424446
// Print out helper function for initializeWithTake
425-
os << " static inline void initializeWithTake(char * _Nonnull "
447+
os << " static ";
448+
ClangSyntaxPrinter(os).printInlineForThunk();
449+
os << "void initializeWithTake(char * _Nonnull "
426450
"destStorage, char * _Nonnull srcStorage) {\n";
427451
ClangValueTypePrinter::printValueWitnessTableAccessAsVariable(
428452
os, typeMetadataFuncName, typeMetadataFuncGenericParams);
@@ -565,7 +589,9 @@ void ClangValueTypePrinter::printTypeGenericTraits(
565589
/*moduleContext=*/nullptr);
566590
}
567591
os << "> {\n";
568-
os << " static inline void * _Nonnull getTypeMetadata() {\n";
592+
os << " static ";
593+
ClangSyntaxPrinter(os).printInlineForThunk();
594+
os << "void * _Nonnull getTypeMetadata() {\n";
569595
os << " return ";
570596
if (!typeDecl->hasClangNode()) {
571597
printer.printBaseName(typeDecl->getModuleContext());

lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ void printPrimitiveGenericTypeTraits(raw_ostream &os, ASTContext &astContext,
186186
<< typeInfo.name << "> = true;\n\n";
187187

188188
os << "template<>\nstruct TypeMetadataTrait<" << typeInfo.name << "> {\n"
189-
<< " static inline void * _Nonnull getTypeMetadata() {\n"
189+
<< " static ";
190+
ClangSyntaxPrinter(os).printInlineForThunk();
191+
os << "void * _Nonnull getTypeMetadata() {\n"
190192
<< " return &" << cxx_synthesis::getCxxImplNamespaceName()
191193
<< "::" << typeMetadataVarName << ";\n"
192194
<< " }\n};\n\n";

0 commit comments

Comments
 (0)