plotfi updated this revision to Diff 462944.
plotfi added a comment.
Updated based on @ahatanak's feedback.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D86049/new/
https://reviews.llvm.org/D86049
Files:
clang/include/clang/AST/DeclObjC.h
clang/lib/AST/DeclObjC.cpp
clang/lib/AST/Mangle.cpp
clang/lib/CodeGen/CGObjC.cpp
clang/lib/CodeGen/CGObjCRuntime.cpp
clang/test/CodeGenObjC/objc-direct-wrapper.m
Index: clang/test/CodeGenObjC/objc-direct-wrapper.m
===================================================================
--- /dev/null
+++ clang/test/CodeGenObjC/objc-direct-wrapper.m
@@ -0,0 +1,63 @@
+// RUN: %clang -fobjc-arc -Wno-objc-root-class -ObjC -fobjc-runtime=ios -FFoundation \
+// RUN: -DENABLE_VISIBLE_OBJC_DIRECT=1 \
+// RUN: -target x86_64-apple-macosx10.15.0 -c -o - %s | \
+// RUN: llvm-nm - | FileCheck -check-prefix=CHECK-WRAPPER %s
+
+// RUN: %clang -fobjc-arc -Wno-objc-root-class \
+// RUN: -target x86_64-apple-macosx10.15.0 \
+// RUN: -ObjC -fobjc-runtime=ios -FFoundation -c -o - %s | llvm-nm - | \
+// RUN: FileCheck -check-prefix=CHECK-DEFAULT %s
+
+// RUN: %clang -fobjc-arc -Wno-objc-root-class \
+// RUN: -DENABLE_VISIBLE_OBJC_DIRECT=1 \
+// RUN: -target x86_64-apple-macosx10.15.0 \
+// RUN: -ObjC -fobjc-runtime=ios -FFoundation -c -o - %s -S -emit-llvm | \
+// RUN: FileCheck -check-prefix=CHECK-WRAPPER-IR-DEF %s
+
+// RUN: %clang -fobjc-arc -Wno-objc-root-class -DNO_OBJC_IMPL \
+// RUN: -DENABLE_VISIBLE_OBJC_DIRECT=1 \
+// RUN: -target x86_64-apple-macosx10.15.0 \
+// RUN: -ObjC -fobjc-runtime=ios -FFoundation -c -o - %s -S -emit-llvm | \
+// RUN: FileCheck -check-prefix=CHECK-WRAPPER-IR-DECLARE %s
+
+// RUN: not %clang -fobjc-arc -Wno-objc-root-class -DENABLE_PROTOCOL_DIRECT_FAIL \
+// RUN: -DENABLE_VISIBLE_OBJC_DIRECT=1 \
+// RUN: -target x86_64-apple-macosx10.15.0 \
+// RUN: -ObjC -fobjc-runtime=ios -FFoundation -c -o - %s -S -emit-llvm 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-PROTOCOL-DIRECT-FAIL %s
+
+// CHECK-WRAPPER: T _-<C testMethod:bar:>
+ // TODO: Fix this
+// CHECK-DEFAULT: t -[C testMethod:bar:]
+// CHECK-WRAPPER-IR-DEF: define {{(dso_local )?}}void @"-<C testMethod:bar:>"
+// CHECK-WRAPPER-IR-DECLARE: declare {{(dso_local )?}}void @"-<C testMethod:bar:>"
+// CHECK-PROTOCOL-DIRECT-FAIL: error: 'objc_direct' attribute cannot be applied to methods declared in an Objective-C protocol
+
+#if ENABLE_VISIBLE_OBJC_DIRECT
+#define OBJC_DIRECT __attribute__((objc_direct)) __attribute__((visibility("default")))
+#else
+#define OBJC_DIRECT
+#endif
+
+@interface C
+- (void)testMethod:(int)arg1 bar:(float)arg2 OBJC_DIRECT;
+@end
+
+#ifndef NO_OBJC_IMPL
+@implementation C
+- (void)testMethod:(int)arg1 bar:(float)arg2 OBJC_DIRECT {
+}
+@end
+#endif
+
+#ifdef ENABLE_PROTOCOL_DIRECT_FAIL
+@protocol ProtoDirectVisibleFail
+- (void)protoMethod OBJC_DIRECT; // expected-error {{'objc_direct' attribute cannot be applied to methods declared in an Objective-C protocol}}
+@end
+#endif
+
+C *c;
+
+void f() {
+ [c testMethod:1 bar:1.0];
+}
Index: clang/lib/CodeGen/CGObjCRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGObjCRuntime.cpp
+++ clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -474,7 +474,8 @@
std::string buffer;
llvm::raw_string_ostream out(buffer);
CGM.getCXXABI().getMangleContext().mangleObjCMethodName(OMD, out,
- /*includePrefixByte=*/true,
+ /*includePrefixByte=*/
+ !OMD->isVisibleDirectMethod(),
includeCategoryName);
return buffer;
}
Index: clang/lib/CodeGen/CGObjC.cpp
===================================================================
--- clang/lib/CodeGen/CGObjC.cpp
+++ clang/lib/CodeGen/CGObjC.cpp
@@ -760,7 +760,9 @@
const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
if (OMD->isDirectMethod()) {
- Fn->setVisibility(llvm::Function::HiddenVisibility);
+ Fn->setVisibility(OMD->isVisibleDirectMethod()
+ ? llvm::Function::DefaultVisibility
+ : llvm::Function::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(OMD, FI, Fn, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(OMD, Fn);
} else {
Index: clang/lib/AST/Mangle.cpp
===================================================================
--- clang/lib/AST/Mangle.cpp
+++ clang/lib/AST/Mangle.cpp
@@ -359,10 +359,16 @@
}
// \01+[ContainerName(CategoryName) SelectorName]
+ // Note: If we are mangling for an objc_direct method with external visibility
+ // then the standard mangling scheme will not work. We must replace the
+ // square braces with angle braces so in the case of visible direct objc
+ // methods it results in: +<ContainerName(CategoryName) SelectorName>
+ // This will include a prefix _ on Darwin.
if (includePrefixByte) {
OS << '\01';
}
- OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
+ OS << (MD->isInstanceMethod() ? '-' : '+');
+ OS << (MD->isVisibleDirectMethod() ? '<' : '[');
if (const auto *CID = MD->getCategory()) {
OS << CID->getClassInterface()->getName();
if (includeCategoryNamespace) {
@@ -376,7 +382,7 @@
}
OS << ' ';
MD->getSelector().print(OS);
- OS << ']';
+ OS << (MD->isVisibleDirectMethod() ? '>' : ']');
}
void MangleContext::mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
Index: clang/lib/AST/DeclObjC.cpp
===================================================================
--- clang/lib/AST/DeclObjC.cpp
+++ clang/lib/AST/DeclObjC.cpp
@@ -23,6 +23,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Visibility.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -838,6 +839,13 @@
!getASTContext().getLangOpts().ObjCDisableDirectMethodsForTesting;
}
+bool ObjCMethodDecl::isVisibleDirectMethod() const {
+ return isDirectMethod() &&
+ this->getExplicitVisibility(VisibilityForValue)
+ .value_or(HiddenVisibility) == DefaultVisibility;
+
+}
+
bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
return getMethodFamily() == OMF_init &&
hasAttr<ObjCDesignatedInitializerAttr>();
Index: clang/include/clang/AST/DeclObjC.h
===================================================================
--- clang/include/clang/AST/DeclObjC.h
+++ clang/include/clang/AST/DeclObjC.h
@@ -487,6 +487,9 @@
/// True if the method is tagged as objc_direct
bool isDirectMethod() const;
+ /// True if the method is tagged as objc_direct and objc_direct_visible
+ bool isVisibleDirectMethod() const;
+
/// True if the method has a parameter that's destroyed in the callee.
bool hasParamDestroyedInCallee() const;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits