summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/ClangASTContext.h2
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile4
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py5
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m79
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h1
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp14
7 files changed, 109 insertions, 3 deletions
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h
index 9537f33b338..5d228e7bdad 100644
--- a/lldb/include/lldb/Symbol/ClangASTContext.h
+++ b/lldb/include/lldb/Symbol/ClangASTContext.h
@@ -845,7 +845,7 @@ public:
// (lldb::opaque_compiler_type_t type, "-[NString
// stringWithCString:]")
const CompilerType &method_compiler_type, lldb::AccessType access,
- bool is_artificial, bool is_variadic);
+ bool is_artificial, bool is_variadic, bool is_objc_direct_call);
static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type,
bool has_extern);
diff --git a/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile b/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile
new file mode 100644
index 00000000000..afecbf96948
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile
@@ -0,0 +1,4 @@
+OBJC_SOURCES := main.m
+LD_EXTRAS := -lobjc -framework Foundation
+
+include Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py b/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py
new file mode 100644
index 00000000000..f0152de1ac3
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py
@@ -0,0 +1,5 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+ __file__, globals(), [decorators.skipUnlessDarwin])
diff --git a/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m b/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m
new file mode 100644
index 00000000000..1a199acdda4
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m
@@ -0,0 +1,79 @@
+#import <Foundation/Foundation.h>
+
+int side_effect = 0;
+
+NSString *str = @"some string";
+
+const char *directCallConflictingName() {
+ return "wrong function";
+}
+
+@interface Foo : NSObject {
+ int instance_var;
+}
+-(int) entryPoint;
+@end
+
+@implementation Foo
+-(int) entryPoint
+{
+ // Try calling directly with self. Same as in the main method otherwise.
+ return 0; //%self.expect("expr [self directCallNoArgs]", substrs=["called directCallNoArgs"])
+ //%self.expect("expr [self directCallArgs: 1111]", substrs=["= 2345"])
+ //%self.expect("expr side_effect = 0; [self directCallVoidReturn]; side_effect", substrs=["= 4321"])
+ //%self.expect("expr [self directCallNSStringArg: str]", substrs=['@"some string"'])
+ //%self.expect("expr [self directCallIdArg: (id)str]", substrs=['@"some string appendix"'])
+ //%self.expect("expr [self directCallConflictingName]", substrs=["correct function"])
+}
+
+// Declare several objc_direct functions we can test.
+-(const char *) directCallNoArgs __attribute__((objc_direct))
+{
+ return "called directCallNoArgs";
+}
+
+-(void) directCallVoidReturn __attribute__((objc_direct))
+{
+ side_effect = 4321;
+}
+
+-(int) directCallArgs:(int)i __attribute__((objc_direct))
+{
+ // Use the arg in some way to make sure that gets passed correctly.
+ return i + 1234;
+}
+
+-(NSString *) directCallNSStringArg:(NSString *)str __attribute__((objc_direct))
+{
+ return str;
+}
+
+-(NSString *) directCallIdArg:(id)param __attribute__((objc_direct))
+{
+ return [param stringByAppendingString:@" appendix"];
+}
+
+// We have another function with the same name above. Make sure this doesn't influence
+// what we call.
+-(const char *) directCallConflictingName __attribute__((objc_direct))
+{
+ return "correct function";
+}
+@end
+
+int main()
+{
+ Foo *foo = [[Foo alloc] init];
+ [foo directCallNoArgs];
+ [foo directCallArgs: 1];
+ [foo directCallVoidReturn];
+ [foo directCallNSStringArg: str];
+ [foo directCallIdArg: (id)str];
+ [foo entryPoint]; //%self.expect("expr [foo directCallNoArgs]", substrs=["called directCallNoArgs"])
+ //%self.expect("expr [foo directCallArgs: 1111]", substrs=["= 2345"])
+ //%self.expect("expr side_effect = 0; [foo directCallVoidReturn]; side_effect", substrs=["= 4321"])
+ //%self.expect("expr [foo directCallNSStringArg: str]", substrs=['@"some string"'])
+ //%self.expect("expr [foo directCallIdArg: (id)str]", substrs=['@"some string appendix"'])
+ //%self.expect("expr [foo directCallConflictingName]", substrs=["correct function"])
+ return 0;
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 0e16153a238..bd97c68bff7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -390,6 +390,10 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
is_complete_objc_class = form_value.Signed();
break;
+ case DW_AT_APPLE_objc_direct:
+ is_objc_direct_call = true;
+ break;
+
case DW_AT_APPLE_runtime_class:
class_language = (LanguageType)form_value.Signed();
break;
@@ -958,7 +962,8 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
clang::ObjCMethodDecl *objc_method_decl =
m_ast.AddMethodToObjCObjectType(
class_opaque_type, attrs.name.GetCString(), clang_type,
- attrs.accessibility, attrs.is_artificial, is_variadic);
+ attrs.accessibility, attrs.is_artificial, is_variadic,
+ attrs.is_objc_direct_call);
type_handled = objc_method_decl != NULL;
if (type_handled) {
LinkDeclContextToDIE(objc_method_decl, die);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index c5b630e435e..4ad757247c3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -244,6 +244,7 @@ struct ParsedDWARFTypeAttributes {
bool is_scoped_enum = false;
bool is_vector = false;
bool is_virtual = false;
+ bool is_objc_direct_call = false;
bool exports_symbols = false;
clang::StorageClass storage = clang::SC_None;
const char *mangled_name = nullptr;
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 95bb4551f2c..3b6b0db3449 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -7769,7 +7769,7 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
// (lldb::opaque_compiler_type_t type, "-[NString
// stringWithCString:]")
const CompilerType &method_clang_type, lldb::AccessType access,
- bool is_artificial, bool is_variadic) {
+ bool is_artificial, bool is_variadic, bool is_objc_direct_call) {
if (!type || !method_clang_type.IsValid())
return nullptr;
@@ -7875,6 +7875,18 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
llvm::ArrayRef<clang::SourceLocation>());
}
+ if (is_objc_direct_call) {
+ // Add a the objc_direct attribute to the declaration we generate that
+ // we generate a direct method call for this ObjCMethodDecl.
+ objc_method_decl->addAttr(
+ clang::ObjCDirectAttr::CreateImplicit(*ast, SourceLocation()));
+ // Usually Sema is creating implicit parameters (e.g., self) when it
+ // parses the method. We don't have a parsing Sema when we build our own
+ // AST here so we manually need to create these implicit parameters to
+ // make the direct call code generation happy.
+ objc_method_decl->createImplicitParams(*ast, class_interface_decl);
+ }
+
class_interface_decl->addDecl(objc_method_decl);
#ifdef LLDB_CONFIGURATION_DEBUG
OpenPOWER on IntegriCloud