Index: packages/Python/lldbsuite/test/expression_command/call-function/TestCallBuiltinFunction.py =================================================================== --- packages/Python/lldbsuite/test/expression_command/call-function/TestCallBuiltinFunction.py +++ packages/Python/lldbsuite/test/expression_command/call-function/TestCallBuiltinFunction.py @@ -0,0 +1,53 @@ +""" +Tests calling builtin functions using expression evaluation. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ExprCommandCallBuiltinFunction(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # Builtins are expanded by Clang, so debug info shouldn't matter. + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number( + 'main.cpp', + '// Please test these expressions while stopped at this line:') + + def test(self): + self.build() + + # Set breakpoint in main and run exe + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + + # Test different builtin functions. + + interp.HandleCommand("expr __builtin_isinf(0.0f)", result) + self.assertEqual(result.GetOutput(), "(int) $0 = 0\n") + + interp.HandleCommand("expr __builtin_isnormal(0.0f)", result) + self.assertEqual(result.GetOutput(), "(int) $1 = 0\n") + + interp.HandleCommand("expr __builtin_constant_p(1)", result) + self.assertEqual(result.GetOutput(), "(int) $2 = 1\n") + + interp.HandleCommand("expr __builtin_abs(-14)", result) + self.assertEqual(result.GetOutput(), "(int) $3 = 14\n") Index: source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h +++ source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h @@ -149,8 +149,6 @@ m_file_manager; ///< The Clang file manager object used by the compiler std::unique_ptr m_compiler; ///< The Clang compiler used to parse expressions into IR - std::unique_ptr - m_builtin_context; ///< Context for Clang built-ins std::unique_ptr m_selector_table; ///< Selector table for Objective-C methods std::unique_ptr Index: source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -508,12 +508,21 @@ // 8. Most of this we get from the CompilerInstance, but we also want to give // the context an ExternalASTSource. m_selector_table.reset(new SelectorTable()); - m_builtin_context.reset(new Builtin::Context()); + + // We enable all builtin functions beside the builtins from libc/libm (e.g. + // 'fopen'). Those libc functions are already correctly handled by LLDB, and + // additionally enabling them as expandable builtins is breaking Clang. + m_compiler->getLangOpts().NoBuiltin = true; + + auto &PP = m_compiler->getPreprocessor(); + auto &builtin_context = PP.getBuiltinInfo(); + builtin_context.initializeBuiltins(PP.getIdentifierTable(), + m_compiler->getLangOpts()); std::unique_ptr ast_context( new ASTContext(m_compiler->getLangOpts(), m_compiler->getSourceManager(), m_compiler->getPreprocessor().getIdentifierTable(), - *m_selector_table.get(), *m_builtin_context.get())); + *m_selector_table.get(), builtin_context)); ast_context->InitBuiltinTypes(m_compiler->getTarget());