Index: include/lldb/Expression/ClangASTSource.h =================================================================== --- include/lldb/Expression/ClangASTSource.h +++ include/lldb/Expression/ClangASTSource.h @@ -52,7 +52,9 @@ m_target (target), m_ast_context (NULL), m_active_lexical_decls (), - m_active_lookups () + m_active_lookups (), + m_allow_objc (true), + m_allow_cxx (true) { m_ast_importer = m_target->GetClangASTImporter(); } @@ -407,6 +409,10 @@ ClangASTImporter *m_ast_importer; ///< The target's AST importer. std::set m_active_lexical_decls; std::set m_active_lookups; + + bool m_allow_objc; + bool m_allow_cxx; + }; //---------------------------------------------------------------------- Index: include/lldb/Expression/ClangExpressionDeclMap.h =================================================================== --- include/lldb/Expression/ClangExpressionDeclMap.h +++ include/lldb/Expression/ClangExpressionDeclMap.h @@ -75,7 +75,9 @@ /// The execution context to use when parsing. //------------------------------------------------------------------ ClangExpressionDeclMap (bool keep_result_in_memory, - ExecutionContext &exe_ctx); + ExecutionContext &exe_ctx, + bool allow_objc = true, + bool allow_cxx = true); //------------------------------------------------------------------ /// Destructor @@ -391,6 +393,9 @@ ClangExpressionVariableList m_found_entities; ///< All entities that were looked up for the parser. ClangExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct. bool m_keep_result_in_memory; ///< True if result persistent variables generated by this expression should stay in memory. + + bool m_allow_cxx; ///< Search for C++ symbols + bool m_allow_objc; ///< Search for ObjC symbols //---------------------------------------------------------------------- /// The following values should not live beyond parsing Index: source/Expression/ClangASTSource.cpp =================================================================== --- source/Expression/ClangASTSource.cpp +++ source/Expression/ClangASTSource.cpp @@ -668,7 +668,7 @@ static ConstString id_name("id"); static ConstString Class_name("Class"); - if (name == id_name || name == Class_name) + if (m_allow_objc && (name == id_name || name == Class_name)) return; if (name_unique_cstr == NULL) Index: source/Expression/ClangExpressionDeclMap.cpp =================================================================== --- source/Expression/ClangExpressionDeclMap.cpp +++ source/Expression/ClangExpressionDeclMap.cpp @@ -51,11 +51,13 @@ using namespace lldb_private; using namespace clang; -ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory, ExecutionContext &exe_ctx) : +ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory, ExecutionContext &exe_ctx, bool allow_objc, bool allow_cxx) : ClangASTSource (exe_ctx.GetTargetSP()), m_found_entities (), m_struct_members (), m_keep_result_in_memory (keep_result_in_memory), + m_allow_cxx (allow_cxx), + m_allow_objc (allow_objc), m_parser_vars (), m_struct_vars () { @@ -995,7 +997,7 @@ static ConstString id_name("id"); static ConstString Class_name("Class"); - if (name == id_name || name == Class_name) + if (m_allow_objc && (name == id_name || name == Class_name)) return; // Only look for functions by name out in our symbols if the function Index: source/Expression/ClangExpressionParser.cpp =================================================================== --- source/Expression/ClangExpressionParser.cpp +++ source/Expression/ClangExpressionParser.cpp @@ -210,12 +210,18 @@ switch (language) { case lldb::eLanguageTypeC: + case lldb::eLanguageTypeC89: + case lldb::eLanguageTypeC99: + case lldb::eLanguageTypeC11: break; case lldb::eLanguageTypeObjC: m_compiler->getLangOpts().ObjC1 = true; m_compiler->getLangOpts().ObjC2 = true; break; case lldb::eLanguageTypeC_plus_plus: + case lldb::eLanguageTypeC_plus_plus_14: + case lldb::eLanguageTypeC_plus_plus_11: + case lldb::eLanguageTypeC_plus_plus_03: m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; m_compiler->getHeaderSearchOpts().UseLibcxx = true; Index: source/Expression/ClangUserExpression.cpp =================================================================== --- source/Expression/ClangUserExpression.cpp +++ source/Expression/ClangUserExpression.cpp @@ -83,7 +83,15 @@ { switch (m_language) { + case lldb::eLanguageTypeC: + case lldb::eLanguageTypeC89: + case lldb::eLanguageTypeC99: + case lldb::eLanguageTypeC11: + break; case lldb::eLanguageTypeC_plus_plus: + case lldb::eLanguageTypeC_plus_plus_14: + case lldb::eLanguageTypeC_plus_plus_11: + case lldb::eLanguageTypeC_plus_plus_03: m_allow_cxx = true; break; case lldb::eLanguageTypeObjC: @@ -525,7 +533,7 @@ m_materializer_ap.reset(new Materializer()); - m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx)); + m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx, m_allow_objc, m_allow_cxx)); class OnExit { Index: test/lang/cpp/restricted_names/Makefile =================================================================== --- /dev/null +++ test/lang/cpp/restricted_names/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Index: test/lang/cpp/restricted_names/TestCppRestrictedNames.py =================================================================== --- /dev/null +++ test/lang/cpp/restricted_names/TestCppRestrictedNames.py @@ -0,0 +1,73 @@ +""" +Test restricted names ('id' and 'Class') in C++. +""" +import lldb +from lldbtest import * +import lldbutil + +class TestCppSizeof(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @dsym_test + def test_with_dsym_and_run_command(self): + self.buildDsym() + self.check() + + @dwarf_test + def test_with_dwarf_and_run_command(self): + self.buildDwarf() + self.check() + + def setUp(self): + TestBase.setUp(self) + + def check(self): + + # Get main source file + src_file = "main.cpp" + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + cwd = os.getcwd() + exe_file = "a.out" + exe_path = os.path.join(cwd, exe_file) + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + main_breakpoint = target.BreakpointCreateBySourceRegex("// break here", src_file_spec) + self.assertTrue(main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT) + + # Launch the process + args = None + env = None + process = target.LaunchSimple(args, env, cwd) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + + # Get current fream of the thread at the breakpoint + frame = thread.GetSelectedFrame() + + # Test result for restricted names (check for wrong result) + self.expect("expression --language c++11 -- Class(2)", substrs = ["= 4"]) + #test_result = frame.EvaluateExpression("Class(2)") + #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 4, "Class(2) = 4") + + self.expect("expression --language c++11 -- Class(3)", substrs = ["= 6"]) + #test_result = frame.EvaluateExpression("Class(3)") + #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 6, "Class(3) = 6") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Index: test/lang/cpp/restricted_names/main.cpp =================================================================== --- /dev/null +++ test/lang/cpp/restricted_names/main.cpp @@ -0,0 +1,7 @@ +int Class(int x) { + return x + x; +} + +int main() { // break here + return 0; +}