[Lldb-commits] [lldb] r152149 - in /lldb/trunk: source/Expression/ClangExpressionDeclMap.cpp test/lang/c/blocks/ test/lang/c/blocks/Makefile test/lang/c/blocks/TestBlocks.py test/lang/c/blocks/main.c

Sean Callanan scallanan at apple.com
Tue Mar 6 13:56:33 PST 2012


Author: spyffe
Date: Tue Mar  6 15:56:33 2012
New Revision: 152149

URL: http://llvm.org/viewvc/llvm-project?rev=152149&view=rev
Log:
Added support for calling blocks from expressions,
but gated by an #ifdef until we roll LLVM/Clang to
bring in the necessary parser support.

Added:
    lldb/trunk/test/lang/c/blocks/
    lldb/trunk/test/lang/c/blocks/Makefile
    lldb/trunk/test/lang/c/blocks/TestBlocks.py
    lldb/trunk/test/lang/c/blocks/main.c
Modified:
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=152149&r1=152148&r2=152149&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Mar  6 15:56:33 2012
@@ -2731,6 +2731,44 @@
     }
 }
 
+static clang_type_t
+MaybePromoteToBlockPointerType
+(
+    ASTContext *ast_context,
+    clang_type_t candidate_type
+)
+{
+    if (!candidate_type)
+        return candidate_type;
+    
+    QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
+    
+    const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_type);
+    
+    if (!candidate_pointer_type)
+        return candidate_type;
+    
+    QualType pointee_qual_type = candidate_pointer_type->getPointeeType();
+    
+    const RecordType *pointee_record_type = dyn_cast<RecordType>(pointee_qual_type);
+    
+    if (!pointee_record_type)
+        return candidate_type;
+    
+    RecordDecl *pointee_record_decl = pointee_record_type->getDecl();
+    
+    if (!pointee_record_decl->isRecord())
+        return candidate_type;
+    
+    if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
+        return candidate_type;
+    
+    QualType generic_function_type = ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
+    QualType block_pointer_type = ast_context->getBlockPointerType(generic_function_type);
+    
+    return block_pointer_type.getAsOpaquePtr();
+}
+
 Value *
 ClangExpressionDeclMap::GetVariableValue
 (
@@ -2768,6 +2806,10 @@
             log->PutCString("There is no AST context for the current execution context");
         return NULL;
     }
+
+#ifdef EXPRESSION_PARSER_SUPPORTS_BLOCKS
+    var_opaque_type = MaybePromoteToBlockPointerType (ast, var_opaque_type);
+#endif
     
     DWARFExpression &var_location_expr = var->LocationExpression();
     

Added: lldb/trunk/test/lang/c/blocks/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/blocks/Makefile?rev=152149&view=auto
==============================================================================
--- lldb/trunk/test/lang/c/blocks/Makefile (added)
+++ lldb/trunk/test/lang/c/blocks/Makefile Tue Mar  6 15:56:33 2012
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/lang/c/blocks/TestBlocks.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/blocks/TestBlocks.py?rev=152149&view=auto
==============================================================================
--- lldb/trunk/test/lang/c/blocks/TestBlocks.py (added)
+++ lldb/trunk/test/lang/c/blocks/TestBlocks.py Tue Mar  6 15:56:33 2012
@@ -0,0 +1,74 @@
+"""Test that lldb can invoke blocks and access variables inside them"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class AnonymousTestCase(TestBase):
+
+    mydir = os.path.join("lang", "c", "blocks")
+    lines = []
+
+    def test_expr_with_dsym(self):
+        self.buildDsym()
+        self.expr()
+
+    def test_expr_with_dwarf(self):
+        self.buildDwarf()
+        self.expr()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line numbers to break at.
+        self.lines.append(line_number('main.c', '// Set breakpoint 0 here.'))
+        self.lines.append(line_number('main.c', '// Set breakpoint 1 here.'))
+
+    def common_setup(self):
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+	self.is_started = False
+
+        # Break inside the foo function which takes a bar_ptr argument.
+	for line in self.lines:
+            self.expect("breakpoint set -f main.c -l %d" % line, BREAKPOINT_CREATED,
+                startstr = "Breakpoint created")
+
+    def wait_for_breakpoint(self):
+        if self.is_started == False:
+            self.is_started = True
+            self.runCmd("process launch", RUN_SUCCEEDED)
+        else:
+            self.runCmd("process continue", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+    # <rdar://problem/10413887>
+    @unittest2.expectedFailure
+    def expr(self):
+        self.common_setup()
+
+        self.wait_for_breakpoint()
+
+        self.expect("expression a + b", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["= 7"])
+
+        self.expect("expression c", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["= 1"])
+
+        self.wait_for_breakpoint()
+
+        # This should display correctly.
+        self.expect("expression (int)neg (-12)", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["= 12"])
+            
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/lang/c/blocks/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/blocks/main.c?rev=152149&view=auto
==============================================================================
--- lldb/trunk/test/lang/c/blocks/main.c (added)
+++ lldb/trunk/test/lang/c/blocks/main.c Tue Mar  6 15:56:33 2012
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+    int c = 1;
+
+    int (^add)(int, int) = ^int(int a, int b)
+    {
+        return a + b + c; // Set breakpoint 0 here.
+    };
+
+    int (^neg)(int) = ^int(int a)
+    {
+        return -a;
+    };
+
+    printf("%d\n", add(3, 4));
+    printf("%d\n", neg(-5)); // Set breakpoint 1 here.
+
+    return 0;
+}





More information about the lldb-commits mailing list