From bfb7c68b5f58391e4c28d290d23abe71bc58a344 Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Mon, 19 Dec 2011 19:38:39 +0000 Subject: [PATCH] Added some strength to the checks that prevent "id" from being found by the parser as an externally-defined type. Before, "id" would sometimes make it through if it was defined in a namespace, but this sometimes caused confusion, for example when it conflicted with std::locale::id. llvm-svn: 146891 --- lldb/source/Expression/ClangASTSource.cpp | 7 +- .../lang/objc/objc-builtin-types/Makefile | 5 ++ .../TestObjCBuiltinTypes.py | 69 +++++++++++++++++++ .../lang/objc/objc-builtin-types/main.cpp | 9 +++ 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 lldb/test/lang/objc/objc-builtin-types/Makefile create mode 100644 lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py create mode 100644 lldb/test/lang/objc/objc-builtin-types/main.cpp diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 1f84185042ad..d368408f1f5d 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -574,12 +574,13 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, TypeList types; SymbolContext null_sc; + if (name == id_name || name == Class_name) + break; + if (module_sp && namespace_decl) module_sp->FindTypes(null_sc, name, &namespace_decl, true, 1, types); - else if(name != id_name && name != Class_name) + else m_target->GetImages().FindTypes(null_sc, name, true, 1, types); - else - break; if (types.GetSize()) { diff --git a/lldb/test/lang/objc/objc-builtin-types/Makefile b/lldb/test/lang/objc/objc-builtin-types/Makefile new file mode 100644 index 000000000000..314f1cb2f077 --- /dev/null +++ b/lldb/test/lang/objc/objc-builtin-types/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py b/lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py new file mode 100644 index 000000000000..480a5f0d1349 --- /dev/null +++ b/lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py @@ -0,0 +1,69 @@ +"""Test that the expression parser doesn't get confused by 'id' and 'Class'""" + +import os, time +import unittest2 +import lldb +import lldbutil +from lldbtest import * + +class TestObjCBuiltinTypes(TestBase): + + mydir = os.path.join("lang", "objc", "objc-builtin-types") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test + + def test_with_dsym_and_python_api(self): + """Test expression parser respect for ObjC built-in types.""" + self.buildDsym() + self.objc_builtin_types() + + @python_api_test + def test_with_dwarf_and_python_api(self): + """Test expression parser respect for ObjC built-in types.""" + self.buildDwarf() + self.objc_builtin_types() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "main.cpp" + self.break_line = line_number(self.main_source, '// Set breakpoint here.') + + # [regression] Can't print ivar value: error: reference to 'id' is ambiguous + def objc_builtin_types(self): + """Test expression parser respect for ObjC built-in types.""" + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation(self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, None, os.getcwd()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue (len(thread_list) != 0, "No thread stopped at our breakpoint.") + self.assertTrue (len(thread_list) == 1, "More than one thread stopped at our breakpoint.") + + # Now make sure we can call a function in the class method we've stopped in. + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue (frame, "Got a valid frame 0 frame.") + + self.expect("expr (foo)", patterns = ["\(ns::id\) \$.* = 0"]) + + self.expect("expr id my_id = 0; my_id", patterns = ["\(id\) \$.* = 0x0"]) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/lang/objc/objc-builtin-types/main.cpp b/lldb/test/lang/objc/objc-builtin-types/main.cpp new file mode 100644 index 000000000000..6dd8cbc6e9fe --- /dev/null +++ b/lldb/test/lang/objc/objc-builtin-types/main.cpp @@ -0,0 +1,9 @@ +namespace ns { + typedef int id; +}; + +int main() +{ + ns::id foo = 0; + return foo; // Set breakpoint here. +}