[clang] [ObjCDirectPreconditionThunk] Adding a flag to with objc_direct symbols' prefix (PR #170616)
Peter Rong via cfe-commits
cfe-commits at lists.llvm.org
Sat Dec 13 00:35:50 PST 2025
https://github.com/DataCorrupted updated https://github.com/llvm/llvm-project/pull/170616
>From 76489044b1150f846af5fe86f07d8d8f32e56179 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Wed, 3 Dec 2025 22:18:02 -0800
Subject: [PATCH 1/4] [ExposeObjCDirect] Adding a flag to allow new objc direct
ABI
1. Add a flag
2. Clean up and set up helper functions to implement later
Signed-off-by: Peter Rong <PeterRong at meta.com>
---
clang/include/clang/AST/DeclObjC.h | 6 ++++
clang/include/clang/Basic/CodeGenOptions.def | 2 ++
clang/include/clang/Options/Options.td | 5 +++
clang/lib/CodeGen/CGObjCRuntime.cpp | 26 +++++++++------
clang/lib/CodeGen/CGObjCRuntime.h | 35 ++++++++++++++++++--
clang/lib/CodeGen/CodeGenModule.h | 26 +++++++++++++++
clang/lib/Driver/ToolChains/Clang.cpp | 4 +++
7 files changed, 90 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index 2541edba83855..e2292cbdea042 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -482,6 +482,12 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
/// True if the method is tagged as objc_direct
bool isDirectMethod() const;
+ /// Check if this direct method can move nil-check to thunk.
+ /// Variadic functions cannot use thunks (musttail incompatible with va_arg)
+ bool canHaveNilCheckThunk() const {
+ return isDirectMethod() && !isVariadic();
+ }
+
/// True if the method has a parameter that's destroyed in the callee.
bool hasParamDestroyedInCallee() const;
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 76a6463881c6f..a7e8564c9e83c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -210,6 +210,8 @@ ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy, Benign)
/// Replace certain message sends with calls to ObjC runtime entrypoints
CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1, Benign)
CODEGENOPT(ObjCAvoidHeapifyLocalBlocks, 1, 0, Benign)
+/// Expose objc_direct method symbols publicly and optimize nil checks.
+CODEGENOPT(ObjCExposeDirectMethods, 1, 0, Benign)
// The optimization options affect frontend options, which in turn do affect the AST.
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 756d6deed7130..ddc04b30cbaa2 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3775,6 +3775,11 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
PosFlag<SetTrue, [], [ClangOption], "Try">,
NegFlag<SetFalse, [], [ClangOption], "Don't try">,
BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
+defm objc_expose_direct_methods : BoolFOption<"objc-expose-direct-methods",
+ CodeGenOpts<"ObjCExposeDirectMethods">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Expose direct method symbols and move nil checks to caller-side thunks">,
+ NegFlag<SetFalse>>;
defm disable_block_signature_string : BoolFOption<"disable-block-signature-string",
CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Disable">,
diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp
index 76e0054f4c9da..38efd4d865284 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -382,11 +382,9 @@ CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
return MessageSendInfo(argsInfo, signatureType);
}
-bool CGObjCRuntime::canMessageReceiverBeNull(CodeGenFunction &CGF,
- const ObjCMethodDecl *method,
- bool isSuper,
- const ObjCInterfaceDecl *classReceiver,
- llvm::Value *receiver) {
+bool CGObjCRuntime::canMessageReceiverBeNull(
+ CodeGenFunction &CGF, const ObjCMethodDecl *method, bool isSuper,
+ const ObjCInterfaceDecl *classReceiver, llvm::Value *receiver) {
// Super dispatch assumes that self is non-null; even the messenger
// doesn't have a null check internally.
if (isSuper)
@@ -399,8 +397,7 @@ bool CGObjCRuntime::canMessageReceiverBeNull(CodeGenFunction &CGF,
// If we're emitting a method, and self is const (meaning just ARC, for now),
// and the receiver is a load of self, then self is a valid object.
- if (auto curMethod =
- dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl)) {
+ if (auto curMethod = dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl)) {
auto self = curMethod->getSelfDecl();
if (self->getType().isConstQualified()) {
if (auto LI = dyn_cast<llvm::LoadInst>(receiver->stripPointerCasts())) {
@@ -416,6 +413,13 @@ bool CGObjCRuntime::canMessageReceiverBeNull(CodeGenFunction &CGF,
return true;
}
+bool CGObjCRuntime::canClassObjectBeUnrealized(
+ const ObjCInterfaceDecl *CalleeClassDecl, CodeGenFunction &CGF) const {
+
+ // Otherwise, assume it can be unrealized.
+ return true;
+}
+
bool CGObjCRuntime::isWeakLinkedClass(const ObjCInterfaceDecl *ID) {
do {
if (ID->isWeakImported())
@@ -466,11 +470,11 @@ clang::CodeGen::emitObjCProtocolObject(CodeGenModule &CGM,
}
std::string CGObjCRuntime::getSymbolNameForMethod(const ObjCMethodDecl *OMD,
- bool includeCategoryName) {
+ bool includeCategoryName,
+ bool includePrefixByte) {
std::string buffer;
llvm::raw_string_ostream out(buffer);
- CGM.getCXXABI().getMangleContext().mangleObjCMethodName(OMD, out,
- /*includePrefixByte=*/true,
- includeCategoryName);
+ CGM.getCXXABI().getMangleContext().mangleObjCMethodName(
+ OMD, out, includePrefixByte, includeCategoryName);
return buffer;
}
diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h
index 72997bf6348ae..1ee3b85e8a779 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.h
+++ b/clang/lib/CodeGen/CGObjCRuntime.h
@@ -117,7 +117,8 @@ class CGObjCRuntime {
virtual ~CGObjCRuntime();
std::string getSymbolNameForMethod(const ObjCMethodDecl *method,
- bool includeCategoryName = true);
+ bool includeCategoryName = true,
+ bool includePrefixByte = true);
/// Generate the function required to register all Objective-C components in
/// this compilation unit with the runtime library.
@@ -322,10 +323,38 @@ class CGObjCRuntime {
MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
QualType resultType,
CallArgList &callArgs);
- bool canMessageReceiverBeNull(CodeGenFunction &CGF,
- const ObjCMethodDecl *method, bool isSuper,
+
+ /// Check if the receiver of an ObjC message send can be null.
+ /// Returns true if the receiver may be null, false if provably non-null.
+ ///
+ /// This can be overridden by subclasses to add runtime-specific heuristics.
+ /// Base implementation checks:
+ /// - Super dispatch (always non-null)
+ /// - Self in const-qualified methods (ARC)
+ /// - Weak-linked classes
+ ///
+ /// Future enhancements in CGObjCCommonMac override:
+ /// - _Nonnull attributes
+ /// - Results of alloc, new, ObjC literals
+ virtual bool canMessageReceiverBeNull(CodeGenFunction &CGF,
+ const ObjCMethodDecl *method,
+ bool isSuper,
const ObjCInterfaceDecl *classReceiver,
llvm::Value *receiver);
+
+ /// Check if a class object can be unrealized (not yet initialized).
+ /// Returns true if the class may be unrealized, false if provably realized.
+ ///
+ /// STUB IMPLEMENTATION: Base class always returns true (conservative).
+ /// Subclasses can override to add runtime-specific dominating-call analysis.
+ ///
+ /// Future: Returns false if:
+ /// - An instance method on the same class was called in a dominating path
+ /// - The class was explicitly realized earlier in control flow
+ /// - Note: [Parent foo] does NOT realize Child (inheritance care needed)
+ virtual bool canClassObjectBeUnrealized(const ObjCInterfaceDecl *ClassDecl,
+ CodeGenFunction &CGF) const;
+
static bool isWeakLinkedClass(const ObjCInterfaceDecl *cls);
/// Destroy the callee-destroyed arguments of the given method,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a253bcda2d06c..f65739de10957 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -717,6 +717,32 @@ class CodeGenModule : public CodeGenTypeCache {
/// Return true iff an Objective-C runtime has been configured.
bool hasObjCRuntime() { return !!ObjCRuntime; }
+ /// Check if a direct method should have its symbol exposed (no \01 prefix).
+ /// This applies to ALL direct methods (including variadic).
+ /// Returns false if OMD is null or not a direct method.
+ bool shouldExposeSymbol(const ObjCMethodDecl *OMD) const {
+ return OMD && OMD->isDirectMethod() &&
+ getLangOpts().ObjCRuntime.isNeXTFamily() &&
+ getCodeGenOpts().ObjCExposeDirectMethods;
+ }
+
+ /// Check if a direct method should use nil-check thunks at call sites.
+ /// This applies only to non-variadic direct methods.
+ /// Variadic methods cannot use thunks (musttail incompatible with va_arg).
+ /// Returns false if OMD is null or not eligible for thunks.
+ bool shouldHaveNilCheckThunk(const ObjCMethodDecl *OMD) const {
+ return OMD && shouldExposeSymbol(OMD) && OMD->canHaveNilCheckThunk();
+ }
+
+ /// Check if a direct method should have inline nil checks at call sites.
+ /// This applies to direct methods that cannot use thunks (e.g., variadic
+ /// methods). These methods get exposed symbols but need inline nil checks
+ /// instead of thunks. Returns false if OMD is null or not eligible for inline
+ /// nil checks.
+ bool shouldHaveNilCheckInline(const ObjCMethodDecl *OMD) const {
+ return OMD && shouldExposeSymbol(OMD) && !OMD->canHaveNilCheckThunk();
+ }
+
const std::string &getModuleNameHash() const { return ModuleNameHash; }
/// Return a reference to the configured OpenCL runtime.
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0380568412e62..2c3beb94f2ef8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4096,6 +4096,10 @@ static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
}
}
+ // Forward -fobjc-expose-direct-methods to cc1
+ if (Args.hasArg(options::OPT_fobjc_expose_direct_methods))
+ CmdArgs.push_back("-fobjc-expose-direct-methods");
+
// When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
// to do Array/Dictionary subscripting by default.
if (Arch == llvm::Triple::x86 && T.isMacOSX() &&
>From b5fd161368aafff8323866990bd351a2d08e2dc6 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Wed, 3 Dec 2025 23:15:45 -0800
Subject: [PATCH 2/4] format
---
clang/lib/CodeGen/CGObjCRuntime.cpp | 2 +-
clang/lib/CodeGen/CGObjCRuntime.h | 22 +++-------------------
2 files changed, 4 insertions(+), 20 deletions(-)
diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp
index 38efd4d865284..a4b4460fdc49c 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -415,7 +415,7 @@ bool CGObjCRuntime::canMessageReceiverBeNull(
bool CGObjCRuntime::canClassObjectBeUnrealized(
const ObjCInterfaceDecl *CalleeClassDecl, CodeGenFunction &CGF) const {
-
+ // TODO
// Otherwise, assume it can be unrealized.
return true;
}
diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h
index 1ee3b85e8a779..0f0cc6ba09200 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.h
+++ b/clang/lib/CodeGen/CGObjCRuntime.h
@@ -324,31 +324,15 @@ class CGObjCRuntime {
QualType resultType,
CallArgList &callArgs);
- /// Check if the receiver of an ObjC message send can be null.
- /// Returns true if the receiver may be null, false if provably non-null.
- ///
- /// This can be overridden by subclasses to add runtime-specific heuristics.
- /// Base implementation checks:
- /// - Super dispatch (always non-null)
- /// - Self in const-qualified methods (ARC)
- /// - Weak-linked classes
- ///
- /// Future enhancements in CGObjCCommonMac override:
- /// - _Nonnull attributes
- /// - Results of alloc, new, ObjC literals
- virtual bool canMessageReceiverBeNull(CodeGenFunction &CGF,
- const ObjCMethodDecl *method,
- bool isSuper,
+ bool canMessageReceiverBeNull(CodeGenFunction &CGF,
+ const ObjCMethodDecl *method, bool isSuper,
const ObjCInterfaceDecl *classReceiver,
llvm::Value *receiver);
/// Check if a class object can be unrealized (not yet initialized).
/// Returns true if the class may be unrealized, false if provably realized.
///
- /// STUB IMPLEMENTATION: Base class always returns true (conservative).
- /// Subclasses can override to add runtime-specific dominating-call analysis.
- ///
- /// Future: Returns false if:
+ /// TODO: Returns false if:
/// - An instance method on the same class was called in a dominating path
/// - The class was explicitly realized earlier in control flow
/// - Note: [Parent foo] does NOT realize Child (inheritance care needed)
>From 488ebbc2d444bc02aafe434166b2c23fe45a381d Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Tue, 9 Dec 2025 14:10:18 -0800
Subject: [PATCH 3/4] update driver behavior and a test
---
clang/lib/Driver/ToolChains/Clang.cpp | 3 ++-
clang/test/Driver/clang_f_opts.c | 8 ++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 2c3beb94f2ef8..193a756cc5f86 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4097,7 +4097,8 @@ static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
}
// Forward -fobjc-expose-direct-methods to cc1
- if (Args.hasArg(options::OPT_fobjc_expose_direct_methods))
+ if (Args.hasFlag(options::OPT_fobjc_expose_direct_methods,
+ options::OPT_fno_objc_expose_direct_methods, false))
CmdArgs.push_back("-fobjc-expose-direct-methods");
// When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index 765f9d6ae3212..2088ceaa3e8f0 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -599,6 +599,14 @@
// CHECK_DISABLE_DIRECT: -fobjc-disable-direct-methods-for-testing
// CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing
+// RUN: %clang -### -xobjective-c -fobjc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_EXPOSE_DIRECT %s
+// RUN: %clang -### -xobjective-c -fno-objc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_NO_EXPOSE_DIRECT %s
+// RUN: %clang -### -xobjective-c -fobjc-expose-direct-methods -fno-objc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_NO_EXPOSE_DIRECT %s
+// RUN: %clang -### -xobjective-c -fno-objc-expose-direct-methods -fobjc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_EXPOSE_DIRECT %s
+// RUN: %clang -### -xobjective-c %s 2>&1 | FileCheck -check-prefix=CHECK_NO_EXPOSE_DIRECT %s
+// CHECK_EXPOSE_DIRECT: "-fobjc-expose-direct-methods"
+// CHECK_NO_EXPOSE_DIRECT-NOT: -fobjc-expose-direct-methods
+
// RUN: %clang -### -S -fjmc --target=x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s
// RUN: %clang -### -S -fjmc --target=x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s
// RUN: %clang -### -S -fjmc -g --target=x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK_JMC %s
>From 465314d87ab9c2661e9c3aef2a1a4f8d371dd7de Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Sat, 13 Dec 2025 00:35:20 -0800
Subject: [PATCH 4/4] Rename to precondition thunk
---
clang/include/clang/AST/DeclObjC.h | 4 +--
clang/include/clang/Basic/CodeGenOptions.def | 4 +--
clang/include/clang/Options/Options.td | 6 ++--
clang/lib/CodeGen/CodeGenModule.h | 30 ++++++++++----------
clang/lib/Driver/ToolChains/Clang.cpp | 8 +++---
clang/test/Driver/clang_f_opts.c | 14 ++++-----
6 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index e2292cbdea042..96c22bfeab735 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -482,9 +482,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
/// True if the method is tagged as objc_direct
bool isDirectMethod() const;
- /// Check if this direct method can move nil-check to thunk.
+ /// Check if this direct method can move precondition-check to thunk.
/// Variadic functions cannot use thunks (musttail incompatible with va_arg)
- bool canHaveNilCheckThunk() const {
+ bool canHavePreconditionThunk() const {
return isDirectMethod() && !isVariadic();
}
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index a7e8564c9e83c..cde7589a3167e 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -210,8 +210,8 @@ ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy, Benign)
/// Replace certain message sends with calls to ObjC runtime entrypoints
CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1, Benign)
CODEGENOPT(ObjCAvoidHeapifyLocalBlocks, 1, 0, Benign)
-/// Expose objc_direct method symbols publicly and optimize nil checks.
-CODEGENOPT(ObjCExposeDirectMethods, 1, 0, Benign)
+/// Generate direct method precondition thunks to expose symbols and optimize nil checks.
+CODEGENOPT(ObjCDirectPreconditionThunk, 1, 0, Benign)
// The optimization options affect frontend options, which in turn do affect the AST.
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index ddc04b30cbaa2..bab2b98f694b0 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3775,10 +3775,10 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
PosFlag<SetTrue, [], [ClangOption], "Try">,
NegFlag<SetFalse, [], [ClangOption], "Don't try">,
BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
-defm objc_expose_direct_methods : BoolFOption<"objc-expose-direct-methods",
- CodeGenOpts<"ObjCExposeDirectMethods">, DefaultFalse,
+defm objc_direct_precondition_thunk : BoolFOption<"objc-direct-precondition-thunk",
+ CodeGenOpts<"ObjCDirectPreconditionThunk">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
- "Expose direct method symbols and move nil checks to caller-side thunks">,
+ "Move direct methods' precondition checks to thunks">,
NegFlag<SetFalse>>;
defm disable_block_signature_string : BoolFOption<"disable-block-signature-string",
CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index f65739de10957..1126bba5eef14 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -717,30 +717,30 @@ class CodeGenModule : public CodeGenTypeCache {
/// Return true iff an Objective-C runtime has been configured.
bool hasObjCRuntime() { return !!ObjCRuntime; }
- /// Check if a direct method should have its symbol exposed (no \01 prefix).
+ /// Check if a direct method should use precondition thunks (exposed symbols).
/// This applies to ALL direct methods (including variadic).
/// Returns false if OMD is null or not a direct method.
- bool shouldExposeSymbol(const ObjCMethodDecl *OMD) const {
+ bool usePreconditionThunk(const ObjCMethodDecl *OMD) const {
return OMD && OMD->isDirectMethod() &&
getLangOpts().ObjCRuntime.isNeXTFamily() &&
- getCodeGenOpts().ObjCExposeDirectMethods;
+ getCodeGenOpts().ObjCDirectPreconditionThunk;
}
- /// Check if a direct method should use nil-check thunks at call sites.
+ /// Check if a direct method should use precondition thunks at call sites.
/// This applies only to non-variadic direct methods.
- /// Variadic methods cannot use thunks (musttail incompatible with va_arg).
- /// Returns false if OMD is null or not eligible for thunks.
- bool shouldHaveNilCheckThunk(const ObjCMethodDecl *OMD) const {
- return OMD && shouldExposeSymbol(OMD) && OMD->canHaveNilCheckThunk();
+ /// Returns false if OMD is null or not eligible for thunks (e.g. variadic
+ /// methods).
+ bool shouldHavePreconditionThunk(const ObjCMethodDecl *OMD) const {
+ return OMD && usePreconditionThunk(OMD) && OMD->canHavePreconditionThunk();
}
- /// Check if a direct method should have inline nil checks at call sites.
- /// This applies to direct methods that cannot use thunks (e.g., variadic
- /// methods). These methods get exposed symbols but need inline nil checks
- /// instead of thunks. Returns false if OMD is null or not eligible for inline
- /// nil checks.
- bool shouldHaveNilCheckInline(const ObjCMethodDecl *OMD) const {
- return OMD && shouldExposeSymbol(OMD) && !OMD->canHaveNilCheckThunk();
+ /// Check if a direct method should have inline precondition checks at call
+ /// sites. This applies to direct methods that cannot use thunks (e.g.,
+ /// variadic methods). These methods get exposed symbols but need inline
+ /// precondition checks instead of thunks.
+ /// Returns false if OMD is null or not eligible.
+ bool shouldHavePreconditionInline(const ObjCMethodDecl *OMD) const {
+ return OMD && usePreconditionThunk(OMD) && !OMD->canHavePreconditionThunk();
}
const std::string &getModuleNameHash() const { return ModuleNameHash; }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 193a756cc5f86..59353f0a81b0c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4096,10 +4096,10 @@ static void RenderObjCOptions(const ToolChain &TC, const Driver &D,
}
}
- // Forward -fobjc-expose-direct-methods to cc1
- if (Args.hasFlag(options::OPT_fobjc_expose_direct_methods,
- options::OPT_fno_objc_expose_direct_methods, false))
- CmdArgs.push_back("-fobjc-expose-direct-methods");
+ // Forward -fobjc-direct-precondition-thunk to cc1
+ if (Args.hasFlag(options::OPT_fobjc_direct_precondition_thunk,
+ options::OPT_fno_objc_direct_precondition_thunk, false))
+ CmdArgs.push_back("-fobjc-direct-precondition-thunk");
// When ObjectiveC legacy runtime is in effect on MacOSX, turn on the option
// to do Array/Dictionary subscripting by default.
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index 2088ceaa3e8f0..1c401f75defd2 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -599,13 +599,13 @@
// CHECK_DISABLE_DIRECT: -fobjc-disable-direct-methods-for-testing
// CHECK_NO_DISABLE_DIRECT-NOT: -fobjc-disable-direct-methods-for-testing
-// RUN: %clang -### -xobjective-c -fobjc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_EXPOSE_DIRECT %s
-// RUN: %clang -### -xobjective-c -fno-objc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_NO_EXPOSE_DIRECT %s
-// RUN: %clang -### -xobjective-c -fobjc-expose-direct-methods -fno-objc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_NO_EXPOSE_DIRECT %s
-// RUN: %clang -### -xobjective-c -fno-objc-expose-direct-methods -fobjc-expose-direct-methods %s 2>&1 | FileCheck -check-prefix=CHECK_EXPOSE_DIRECT %s
-// RUN: %clang -### -xobjective-c %s 2>&1 | FileCheck -check-prefix=CHECK_NO_EXPOSE_DIRECT %s
-// CHECK_EXPOSE_DIRECT: "-fobjc-expose-direct-methods"
-// CHECK_NO_EXPOSE_DIRECT-NOT: -fobjc-expose-direct-methods
+// RUN: %clang -### -xobjective-c -fobjc-direct-precondition-thunk %s 2>&1 | FileCheck -check-prefix=CHECK_DIRECT_PRECONDITION_THUNK %s
+// RUN: %clang -### -xobjective-c -fno-objc-direct-precondition-thunk %s 2>&1 | FileCheck -check-prefix=CHECK_NO_DIRECT_PRECONDITION_THUNK %s
+// RUN: %clang -### -xobjective-c -fobjc-direct-precondition-thunk -fno-objc-direct-precondition-thunk %s 2>&1 | FileCheck -check-prefix=CHECK_NO_DIRECT_PRECONDITION_THUNK %s
+// RUN: %clang -### -xobjective-c -fno-objc-direct-precondition-thunk -fobjc-direct-precondition-thunk %s 2>&1 | FileCheck -check-prefix=CHECK_DIRECT_PRECONDITION_THUNK %s
+// RUN: %clang -### -xobjective-c %s 2>&1 | FileCheck -check-prefix=CHECK_NO_DIRECT_PRECONDITION_THUNK %s
+// CHECK_DIRECT_PRECONDITION_THUNK: "-fobjc-direct-precondition-thunk"
+// CHECK_NO_DIRECT_PRECONDITION_THUNK-NOT: -fobjc-direct-precondition-thunk
// RUN: %clang -### -S -fjmc --target=x86_64-unknown-linux %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s
// RUN: %clang -### -S -fjmc --target=x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefixes=CHECK_JMC_WARN,CHECK_NOJMC %s
More information about the cfe-commits
mailing list