From scallanan at apple.com Mon Jul 26 17:14:36 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 26 Jul 2010 22:14:36 -0000 Subject: [Lldb-commits] [lldb] r109454 - /lldb/trunk/source/Expression/ClangFunction.cpp Message-ID: <20100726221436.80A022A6C12C@llvm.org> Author: spyffe Date: Mon Jul 26 17:14:36 2010 New Revision: 109454 URL: http://llvm.org/viewvc/llvm-project?rev=109454&view=rev Log: Fixed a bug where we didn't restore thread and frame state after running a function. This caused nondeterministic crashes in the expression evaluation code. Modified: lldb/trunk/source/Expression/ClangFunction.cpp Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=109454&r1=109453&r2=109454&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Mon Jul 26 17:14:36 2010 @@ -247,9 +247,9 @@ } bool -ClangFunction::WriteFunctionWrapper (ExecutionContext &exc_context, Stream &errors) +ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors) { - Process *process = exc_context.process; + Process *process = exe_ctx.process; if (process == NULL) return false; @@ -257,10 +257,10 @@ if (!m_JITted) { // Next we should JIT it and insert the result into the target program. - if (!JITFunction (exc_context, m_wrapper_function_name.c_str())) + if (!JITFunction (exe_ctx, m_wrapper_function_name.c_str())) return false; - if (!WriteJITCode (exc_context)) + if (!WriteJITCode (exe_ctx)) return false; m_JITted = true; @@ -275,15 +275,15 @@ } bool -ClangFunction::WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors) +ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors) { - return WriteFunctionArguments(exc_context, args_addr_ref, m_function_addr, m_arg_values, errors); + return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors); } // FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function. bool -ClangFunction::WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors) +ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors) { // Otherwise, allocate space for the argument passing struct, and write it. // We use the information in the expression parser AST to @@ -295,7 +295,7 @@ using namespace clang; ExecutionResults return_value = eExecutionSetupError; - Process *process = exc_context.process; + Process *process = exe_ctx.process; if (process == NULL) return return_value; @@ -321,7 +321,7 @@ // FIXME: This is fake, and just assumes that it matches that architecture. // Make a data extractor and put the address into the right byte order & size. - uint64_t fun_addr = function_address.GetLoadAddress(exc_context.process); + uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.process); int first_offset = m_struct_layout->getFieldOffset(0)/8; process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error); @@ -352,7 +352,7 @@ ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType())) continue; - const Scalar &arg_scalar = arg_value->ResolveValue(&exc_context, m_clang_ast_context->getASTContext()); + const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext()); int byte_size = arg_scalar.GetByteSize(); std::vector buffer; @@ -367,15 +367,15 @@ } bool -ClangFunction::InsertFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors) +ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors) { using namespace clang; if (CompileFunction(errors) != 0) return false; - if (!WriteFunctionWrapper(exc_context, errors)) + if (!WriteFunctionWrapper(exe_ctx, errors)) return false; - if (!WriteFunctionArguments(exc_context, args_addr_ref, errors)) + if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors)) return false; Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); @@ -386,11 +386,11 @@ } ThreadPlan * -ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t func_addr, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error) +ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t func_addr, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error) { // FIXME: Use the errors Stream for better error reporting. - Process *process = exc_context.process; + Process *process = exe_ctx.process; if (process == NULL) { @@ -401,7 +401,7 @@ // Okay, now run the function: Address wrapper_address (NULL, func_addr); - ThreadPlan *new_plan = new ThreadPlanCallFunction (*exc_context.thread, + ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread, wrapper_address, args_addr, stop_others, discard_on_error); @@ -409,14 +409,14 @@ } bool -ClangFunction::FetchFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr, Value &ret_value) +ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value) { // Read the return value - it is the last field in the struct: // FIXME: How does clang tell us there's no return value? We need to handle that case. std::vector data_buffer; data_buffer.resize(m_return_size); - Process *process = exc_context.process; + Process *process = exe_ctx.process; Error error; size_t bytes_read = process->ReadMemory(args_addr + m_return_offset/8, &data_buffer.front(), m_return_size, error); @@ -441,43 +441,43 @@ } void -ClangFunction::DeallocateFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr) +ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr) { std::list::iterator pos; pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr); if (pos != m_wrapper_args_addrs.end()) m_wrapper_args_addrs.erase(pos); - exc_context.process->DeallocateMemory(args_addr); + exe_ctx.process->DeallocateMemory(args_addr); } ClangFunction::ExecutionResults -ClangFunction::ExecuteFunction(ExecutionContext &exc_context, Stream &errors, Value &results) +ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results) { - return ExecuteFunction (exc_context, errors, 1000, true, results); + return ExecuteFunction (exe_ctx, errors, 1000, true, results); } ClangFunction::ExecutionResults -ClangFunction::ExecuteFunction(ExecutionContext &exc_context, Stream &errors, bool stop_others, Value &results) +ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results) { - return ExecuteFunction (exc_context, NULL, errors, stop_others, NULL, false, results); + return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results); } ClangFunction::ExecutionResults ClangFunction::ExecuteFunction( - ExecutionContext &exc_context, + ExecutionContext &exe_ctx, Stream &errors, uint32_t single_thread_timeout_usec, bool try_all_threads, Value &results) { - return ExecuteFunction (exc_context, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results); + return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results); } // This is the static function ClangFunction::ExecutionResults ClangFunction::ExecuteFunction ( - ExecutionContext &exc_context, + ExecutionContext &exe_ctx, lldb::addr_t function_address, lldb::addr_t &void_arg, bool stop_others, @@ -485,9 +485,12 @@ uint32_t single_thread_timeout_usec, Stream &errors) { + // Save this value for restoration of the execution context after we run + uint32_t tid = exe_ctx.thread->GetID(); + ClangFunction::ExecutionResults return_value = eExecutionSetupError; - lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exc_context, function_address, void_arg, errors, stop_others, false)); + lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false)); ThreadPlanCallFunction *call_plan_ptr = static_cast (call_plan_sp.get()); @@ -495,7 +498,7 @@ return eExecutionSetupError; call_plan_sp->SetPrivate(true); - exc_context.thread->QueueThreadPlan(call_plan_sp, true); + exe_ctx.thread->QueueThreadPlan(call_plan_sp, true); // We need to call the function synchronously, so spin waiting for it to return. // If we get interrupted while executing, we're going to lose our context, and @@ -511,7 +514,7 @@ timeout_ptr = &real_timeout; } - exc_context.process->Resume (); + exe_ctx.process->Resume (); Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); @@ -521,7 +524,7 @@ // Now wait for the process to stop again: // FIXME: Probably want a time out. - lldb::StateType stop_state = exc_context.process->WaitForStateChangedEvents (timeout_ptr, event_sp); + lldb::StateType stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp); if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL) { @@ -531,11 +534,11 @@ if (log) log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec); - if (exc_context.process->Halt().Success()) + if (exe_ctx.process->Halt().Success()) { timeout_ptr = NULL; - stop_state = exc_context.process->WaitForStateChangedEvents (timeout_ptr, event_sp); + stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp); if (stop_state == lldb::eStateInvalid) { errors.Printf ("Got an invalid stop state after halt."); @@ -552,14 +555,14 @@ { // Between the time that we got the timeout and the time we halted, but target // might have actually completed the plan. If so, we're done. - if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get())) + if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get())) { return_value = eExecutionCompleted; break; } call_plan_ptr->SetStopOthers (false); - exc_context.process->Resume(); + exe_ctx.process->Resume(); continue; } else @@ -569,12 +572,12 @@ if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping) continue; - if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get())) + if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get())) { return_value = eExecutionCompleted; break; } - else if (exc_context.thread->WasThreadPlanDiscarded (call_plan_sp.get())) + else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get())) { return_value = eExecutionDiscarded; break; @@ -652,12 +655,17 @@ } } + // Thread we ran the function in may have gone away because we ran the target + // Check that it's still there. + exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByID(tid, true).get(); + exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get(); + return return_value; } ClangFunction::ExecutionResults ClangFunction::ExecuteFunction( - ExecutionContext &exc_context, + ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, Stream &errors, bool stop_others, @@ -680,11 +688,11 @@ if (args_addr == LLDB_INVALID_ADDRESS) { - if (!InsertFunction(exc_context, args_addr, errors)) + if (!InsertFunction(exe_ctx, args_addr, errors)) return eExecutionSetupError; } - return_value = ClangFunction::ExecuteFunction(exc_context, m_wrapper_function_addr, args_addr, stop_others, try_all_threads, single_thread_timeout_usec, errors); + return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others, try_all_threads, single_thread_timeout_usec, errors); if (args_addr_ptr != NULL) *args_addr_ptr = args_addr; @@ -692,22 +700,22 @@ if (return_value != eExecutionCompleted) return return_value; - FetchFunctionResults(exc_context, args_addr, results); + FetchFunctionResults(exe_ctx, args_addr, results); if (args_addr_ptr == NULL) - DeallocateFunctionResults(exc_context, args_addr); + DeallocateFunctionResults(exe_ctx, args_addr); return eExecutionCompleted; } ClangFunction::ExecutionResults -ClangFunction::ExecuteFunctionWithABI(ExecutionContext &exc_context, Stream &errors, Value &results) +ClangFunction::ExecuteFunctionWithABI(ExecutionContext &exe_ctx, Stream &errors, Value &results) { // FIXME: Use the errors Stream for better error reporting. using namespace clang; ExecutionResults return_value = eExecutionSetupError; - Process *process = exc_context.process; + Process *process = exe_ctx.process; if (process == NULL) { @@ -719,9 +727,9 @@ //unsigned int arg_index; //for (arg_index = 0; arg_index < num_args; ++arg_index) - // m_arg_values.GetValueAtIndex(arg_index)->ResolveValue(&exc_context, GetASTContext()); + // m_arg_values.GetValueAtIndex(arg_index)->ResolveValue(&exe_ctx, GetASTContext()); - ThreadPlan *call_plan = exc_context.thread->QueueThreadPlanForCallFunction (false, + ThreadPlan *call_plan = exe_ctx.thread->QueueThreadPlanForCallFunction (false, m_function_addr, m_arg_values, true); @@ -746,12 +754,12 @@ if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping) continue; - if (exc_context.thread->IsThreadPlanDone (call_plan)) + if (exe_ctx.thread->IsThreadPlanDone (call_plan)) { return_value = eExecutionCompleted; break; } - else if (exc_context.thread->WasThreadPlanDiscarded (call_plan)) + else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan)) { return_value = eExecutionDiscarded; break; From scallanan at apple.com Mon Jul 26 19:55:47 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 27 Jul 2010 00:55:47 -0000 Subject: [Lldb-commits] [lldb] r109476 - in /lldb/trunk: include/lldb/Core/ModuleList.h include/lldb/Expression/ClangASTSource.h include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Symbol/SymbolContext.h source/Commands/CommandObjectCall.cpp source/Core/Disassembler.cpp source/Core/ModuleList.cpp source/Expression/ClangASTSource.cpp source/Expression/ClangExpressionDeclMap.cpp source/Symbol/SymbolContext.cpp Message-ID: <20100727005547.DA9822A6C12C@llvm.org> Author: spyffe Date: Mon Jul 26 19:55:47 2010 New Revision: 109476 URL: http://llvm.org/viewvc/llvm-project?rev=109476&view=rev Log: Changed SymbolContext so when you search for functions it returns a list of functions as a SymbolContextList. Rewrote the clients of SymbolContext to use this SymbolContextList. Rewrote some of the providers of the data to SymbolContext to make them respect preferences as to whether the list should be cleared first; propagated that change out. ClangExpressionDeclMap and ClangASTSource use this new function list to properly generate function definitions - even for functions that don't have a prototype in the debug information. Modified: lldb/trunk/include/lldb/Core/ModuleList.h lldb/trunk/include/lldb/Expression/ClangASTSource.h lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Symbol/SymbolContext.h lldb/trunk/source/Commands/CommandObjectCall.cpp lldb/trunk/source/Core/Disassembler.cpp lldb/trunk/source/Core/ModuleList.cpp lldb/trunk/source/Expression/ClangASTSource.cpp lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Symbol/SymbolContext.cpp Modified: lldb/trunk/include/lldb/Core/ModuleList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleList.h?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ModuleList.h (original) +++ lldb/trunk/include/lldb/Core/ModuleList.h Mon Jul 26 19:55:47 2010 @@ -160,6 +160,7 @@ size_t FindFunctions (const ConstString &name, uint32_t name_type_mask, + bool append, SymbolContextList &sc_list); //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Expression/ClangASTSource.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangASTSource.h?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangASTSource.h (original) +++ lldb/trunk/include/lldb/Expression/ClangASTSource.h Mon Jul 26 19:55:47 2010 @@ -61,6 +61,7 @@ clang::ASTContext *GetASTContext(); clang::NamedDecl *AddVarDecl(void *type); clang::NamedDecl *AddFunDecl(void *type); + clang::NamedDecl *AddGenericFunDecl(); }; } Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Mon Jul 26 19:55:47 2010 @@ -157,7 +157,7 @@ TypeFromParser *parser_type = NULL); void AddOneVariable(NameSearchContext &context, Variable *var); - void AddOneFunction(NameSearchContext &context, Function *fun); + void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym); bool DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Mon Jul 26 19:55:47 2010 @@ -195,10 +195,12 @@ /// symbol context. /// /// @return - /// A shared pointer to the function found. + /// The number of symbol contexts found. //------------------------------------------------------------------ - Function * - FindFunctionByName (const char *name) const; + size_t + FindFunctionsByName (const ConstString &name, + bool append, + SymbolContextList &sc_list) const; //------------------------------------------------------------------ /// Find a variable matching the given name, working out from this Modified: lldb/trunk/source/Commands/CommandObjectCall.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCall.cpp?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCall.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCall.cpp Mon Jul 26 19:55:47 2010 @@ -169,9 +169,20 @@ //const char *return_type = command.GetArgumentAtIndex(0); const char *function_name = command.GetArgumentAtIndex(1); // Look up the called function: + + Function *target_fn = NULL; + + SymbolContextList sc_list; + + exe_ctx.frame->GetSymbolContext(eSymbolContextEverything).FindFunctionsByName(ConstString(function_name), false, sc_list); - Function *target_fn = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything).FindFunctionByName (function_name); - + if (sc_list.GetSize() > 0) + { + SymbolContext sc; + sc_list.GetContextAtIndex(0, sc); + target_fn = sc.function; + } + // FIXME: If target_fn is NULL, we should look up the name as a symbol and use it and the provided // return type. Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Mon Jul 26 19:55:47 2010 @@ -115,7 +115,8 @@ else { if (exe_ctx.target->GetImages().FindFunctions (name, - eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, + eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, + false, sc_list)) { return Disassemble (debugger, arch, exe_ctx, sc_list, num_mixed_context_lines, show_bytes, strm); Modified: lldb/trunk/source/Core/ModuleList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/source/Core/ModuleList.cpp (original) +++ lldb/trunk/source/Core/ModuleList.cpp Mon Jul 26 19:55:47 2010 @@ -126,15 +126,18 @@ } size_t -ModuleList::FindFunctions (const ConstString &name, uint32_t name_type_mask, SymbolContextList &sc_list) +ModuleList::FindFunctions (const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList &sc_list) { - sc_list.Clear(); + if (!append) + sc_list.Clear(); + Mutex::Locker locker(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { (*pos)->FindFunctions (name, name_type_mask, true, sc_list); } + return sc_list.GetSize(); } Modified: lldb/trunk/source/Expression/ClangASTSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangASTSource.cpp (original) +++ lldb/trunk/source/Expression/ClangASTSource.cpp Mon Jul 26 19:55:47 2010 @@ -146,3 +146,19 @@ return Decl; } + +clang::NamedDecl *NameSearchContext::AddGenericFunDecl() +{ + QualType generic_function_type(ASTSource.Context.getFunctionType(ASTSource.Context.getSizeType(), // result + NULL, // argument types + 0, // number of arguments + true, // variadic? + 0, // type qualifiers + false, // has exception specification? + false, // has any exception specification? + 0, // number of exceptions + NULL, // exceptions + FunctionType::ExtInfo())); // defaults for noreturn, regparm, calling convention + + return AddFunDecl(generic_function_type.getAsOpaquePtr()); +} Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Jul 26 19:55:47 2010 @@ -603,12 +603,23 @@ } ConstString name_cs(name); + SymbolContextList sym_ctxs; - Function *fn = m_sym_ctx->FindFunctionByName(name_cs.GetCString()); + m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs); + + for (uint32_t index = 0, num_indices = sym_ctxs.GetSize(); + index < num_indices; + ++index) + { + SymbolContext sym_ctx; + sym_ctxs.GetContextAtIndex(index, sym_ctx); + + if (sym_ctx.function) + AddOneFunction(context, sym_ctx.function, NULL); + else if(sym_ctx.symbol) + AddOneFunction(context, NULL, sym_ctx.symbol); + } - if (fn) - AddOneFunction(context, fn); - Variable *var = FindVariableInScope(*m_sym_ctx, name); if (var) @@ -749,41 +760,64 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, - Function* fun) + Function* fun, + Symbol* symbol) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - Type *fun_type = fun->GetType(); - if (!fun_type) - { - if (log) - log->PutCString("Skipped a function because it has no type"); - return; - } + NamedDecl *fun_decl; + std::auto_ptr fun_location(new Value); + const Address *fun_address; - void *fun_opaque_type = fun_type->GetOpaqueClangQualType(); + // only valid for Functions, not for Symbols + void *fun_opaque_type = NULL; + clang::ASTContext *fun_ast_context = NULL; - if (!fun_opaque_type) + if (fun) + { + Type *fun_type = fun->GetType(); + + if (!fun_type) + { + if (log) + log->PutCString("Skipped a function because it has no type"); + return; + } + + fun_opaque_type = fun_type->GetOpaqueClangQualType(); + + if (!fun_opaque_type) + { + if (log) + log->PutCString("Skipped a function because it has no Clang type"); + return; + } + + fun_address = &fun->GetAddressRange().GetBaseAddress(); + + TypeList *type_list = fun_type->GetTypeList(); + fun_ast_context = type_list->GetClangASTContext().getASTContext(); + void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type); + + fun_decl = context.AddFunDecl(copied_type); + } + else if (symbol) + { + fun_address = &symbol->GetAddressRangeRef().GetBaseAddress(); + + fun_decl = context.AddGenericFunDecl(); + } + else { if (log) - log->PutCString("Skipped a function because it has no Clang type"); + log->PutCString("AddOneFunction called with no function and no symbol"); return; } - std::auto_ptr fun_location(new Value); - - const Address &fun_address = fun->GetAddressRange().GetBaseAddress(); - lldb::addr_t load_addr = fun_address.GetLoadAddress(m_exe_ctx->process); + lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->process); fun_location->SetValueType(Value::eValueTypeLoadAddress); fun_location->GetScalar() = load_addr; - TypeList *type_list = fun_type->GetTypeList(); - clang::ASTContext *fun_ast_context = type_list->GetClangASTContext().getASTContext(); - void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type); - - NamedDecl *fun_decl = context.AddFunDecl(copied_type); - Tuple tuple; tuple.m_decl = fun_decl; Modified: lldb/trunk/source/Symbol/SymbolContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=109476&r1=109475&r2=109476&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolContext.cpp (original) +++ lldb/trunk/source/Symbol/SymbolContext.cpp Mon Jul 26 19:55:47 2010 @@ -354,17 +354,18 @@ } -Function * -SymbolContext::FindFunctionByName (const char *name) const -{ - ConstString name_const_str (name); +size_t +SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const +{ + if (!append) + sc_list.Clear(); + if (function != NULL) { // FIXME: Look in the class of the current function, if it exists, // for methods matching name. } - // if (comp_unit != NULL) { // Make sure we've read in all the functions. We should be able to check and see @@ -374,33 +375,24 @@ lldb::FunctionSP func_sp; for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx) { - if (func_sp->GetMangled().GetName() == name_const_str) - return func_sp.get(); + if (func_sp->GetMangled().GetName() == name) + { + SymbolContext sym_ctx(target_sp, + module_sp, + comp_unit, + func_sp.get()); + sc_list.Append(sym_ctx); + } } } + if (module_sp != NULL) - { - SymbolContextList sc_matches; - if (module_sp->FindFunctions (name_const_str, eFunctionNameTypeBase | eFunctionNameTypeFull, false, sc_matches) > 0) - { - SymbolContext sc; - sc_matches.GetContextAtIndex (0, sc); - return sc.function; - } - } + module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list); if (target_sp) - { - SymbolContextList sc_matches; - if (target_sp->GetImages().FindFunctions (name_const_str, eFunctionNameTypeBase | eFunctionNameTypeFull, sc_matches) > 0) - { - SymbolContext sc; - sc_matches.GetContextAtIndex (0, sc); - return sc.function; - } - } + target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list); - return NULL; + return sc_list.GetSize(); } lldb::VariableSP From scallanan at apple.com Mon Jul 26 20:17:28 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 27 Jul 2010 01:17:28 -0000 Subject: [Lldb-commits] [lldb] r109477 - /lldb/trunk/source/Expression/IRForTarget.cpp Message-ID: <20100727011728.B391E2A6C12C@llvm.org> Author: spyffe Date: Mon Jul 26 20:17:28 2010 New Revision: 109477 URL: http://llvm.org/viewvc/llvm-project?rev=109477&view=rev Log: Fixed a bug in the IR transformer where we were trying to do replaceUsesOfWith on a constant, which doesn't work. Turns out we don't need to do anything for constants. Modified: lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=109477&r1=109476&r2=109477&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Jul 26 20:17:28 2010 @@ -186,7 +186,16 @@ for (ui = guard_load->use_begin(); ui != guard_load->use_end(); ++ui) - ui->replaceUsesOfWith(guard_load, zero); + { + if (isa(ui)) + { + // do nothing for the moment + } + else + { + ui->replaceUsesOfWith(guard_load, zero); + } + } guard_load->eraseFromParent(); } From scallanan at apple.com Mon Jul 26 21:07:53 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 27 Jul 2010 02:07:53 -0000 Subject: [Lldb-commits] [lldb] r109483 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/IRForTarget.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp Message-ID: <20100727020754.015A12A6C12C@llvm.org> Author: spyffe Date: Mon Jul 26 21:07:53 2010 New Revision: 109483 URL: http://llvm.org/viewvc/llvm-project?rev=109483&view=rev Log: Added support for locating a function that is referenced in the IR. We don't yet support updating the call to that function. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=109483&r1=109482&r2=109483&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Mon Jul 26 21:07:53 2010 @@ -88,6 +88,8 @@ off_t &offset, uint32_t index); + uint64_t GetFunctionAddress (const clang::NamedDecl *decl); + // Interface for DwarfExpression Value *GetValueForIndex (uint32_t index); Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=109483&r1=109482&r2=109483&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Mon Jul 26 21:07:53 2010 @@ -14,6 +14,7 @@ namespace llvm { class BasicBlock; + class CallInst; class Function; class Module; class TargetData; @@ -37,15 +38,18 @@ llvm::PassManagerType getPotentialPassManagerType() const; private: bool MaybeHandleVariable(llvm::Module &M, - lldb_private::ClangExpressionDeclMap *DM, llvm::Value *V, bool Store); + bool MaybeHandleCall(llvm::Module &M, + llvm::CallInst *C); bool runOnBasicBlock(llvm::Module &M, llvm::BasicBlock &BB); bool removeGuards(llvm::Module &M, llvm::BasicBlock &BB); bool replaceVariables(llvm::Module &M, llvm::Function *F); + bool replaceFunctions(llvm::Module &M, + llvm::Function *F); lldb_private::ClangExpressionDeclMap *m_decl_map; const llvm::TargetData *m_target_data; Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=109483&r1=109482&r2=109483&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Jul 26 21:07:53 2010 @@ -182,6 +182,24 @@ return true; } +uint64_t +ClangExpressionDeclMap::GetFunctionAddress (const clang::NamedDecl *decl) +{ + TupleIterator iter; + + for (iter = m_tuples.begin(); + iter != m_tuples.end(); + ++iter) + { + if (decl == iter->m_decl) + { + return iter->m_value->GetScalar().ULongLong(); + } + } + + return 0; +} + // Interface for DwarfExpression lldb_private::Value *ClangExpressionDeclMap::GetValueForIndex (uint32_t index) Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=109483&r1=109482&r2=109483&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Jul 26 21:07:53 2010 @@ -82,7 +82,6 @@ bool IRForTarget::MaybeHandleVariable(Module &M, - lldb_private::ClangExpressionDeclMap *DM, llvm::Value *V, bool Store) { @@ -110,13 +109,13 @@ size_t value_size = m_target_data->getTypeStoreSize(value_type); off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type); - if (named_decl && !DM->AddValueToStruct(V, - named_decl, - name, - qual_type, - ast_context, - value_size, - value_alignment)) + if (named_decl && !m_decl_map->AddValueToStruct(V, + named_decl, + name, + qual_type, + ast_context, + value_size, + value_alignment)) return false; } @@ -124,6 +123,41 @@ } bool +IRForTarget::MaybeHandleCall(Module &M, + CallInst *C) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + llvm::Function *fun = C->getCalledFunction(); + + if (fun == NULL) + return true; + + clang::NamedDecl *fun_decl = DeclForGlobalValue(M, fun); + + if (!fun_decl) + { + if (log) + log->Printf("Function %s wasn't in the metadata", fun->getName().str().c_str()); + return false; + } + + uint64_t fun_addr = m_decl_map->GetFunctionAddress(fun_decl); + + if (fun_addr == 0) + { + if (log) + log->Printf("Function %s had no address", fun_decl->getNameAsCString()); + return false; + } + + if (log) + log->Printf("Found %s at %llx", fun_decl->getNameAsCString(), fun_addr); + + return true; +} + +bool IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB) { ///////////////////////////////////////////////////////////////////////// @@ -139,11 +173,15 @@ Instruction &inst = *ii; if (LoadInst *load = dyn_cast(&inst)) - if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false)) + if (!MaybeHandleVariable(M, load->getPointerOperand(), false)) return false; if (StoreInst *store = dyn_cast(&inst)) - if (!MaybeHandleVariable(M, m_decl_map, store->getPointerOperand(), false)) + if (!MaybeHandleVariable(M, store->getPointerOperand(), true)) + return false; + + if (CallInst *call = dyn_cast(&inst)) + if (!MaybeHandleCall(M, call)) return false; } From johnny.chen at apple.com Tue Jul 27 15:59:06 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Jul 2010 20:59:06 -0000 Subject: [Lldb-commits] [lldb] r109539 - in /lldb/trunk/test: dead-strip/TestDeadStrip.py function_types/TestFunctionTypes.py global_variables/TestGlobalVariables.py load_unload/TestLoadUnload.py order/TestOrder.py set_values/TestSetValues.py Message-ID: <20100727205907.0D4212A6C12C@llvm.org> Author: johnny Date: Tue Jul 27 15:59:06 2010 New Revision: 109539 URL: http://llvm.org/viewvc/llvm-project?rev=109539&view=rev Log: Fixed typos from cut-and-paste errors. Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/order/TestOrder.py lldb/trunk/test/set_values/TestSetValues.py Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=109539&r1=109538&r2=109539&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Tue Jul 27 15:59:06 2010 @@ -7,7 +7,7 @@ import lldb import lldbtest -class TestClassTypes(lldbtest.TestBase): +class TestDeadStrip(lldbtest.TestBase): mydir = "dead-strip" Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=109539&r1=109538&r2=109539&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Tue Jul 27 15:59:06 2010 @@ -5,7 +5,7 @@ import lldb import lldbtest -class TestClassTypes(lldbtest.TestBase): +class TestFunctionTypes(lldbtest.TestBase): mydir = "function_types" Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=109539&r1=109538&r2=109539&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Tue Jul 27 15:59:06 2010 @@ -5,7 +5,7 @@ import lldb import lldbtest -class TestClassTypes(lldbtest.TestBase): +class TestGlobalVariables(lldbtest.TestBase): mydir = "global_variables" Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=109539&r1=109538&r2=109539&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Tue Jul 27 15:59:06 2010 @@ -7,11 +7,11 @@ import lldb import lldbtest -class TestClassTypes(lldbtest.TestBase): +class TestLoadUnload(lldbtest.TestBase): mydir = "load_unload" - def test_dead_strip(self): + def test_load_unload(self): """Test breakpoint by name works correctly with dlopen'ing.""" res = self.res exe = os.path.join(os.getcwd(), "a.out") Modified: lldb/trunk/test/order/TestOrder.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrder.py?rev=109539&r1=109538&r2=109539&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrder.py (original) +++ lldb/trunk/test/order/TestOrder.py Tue Jul 27 15:59:06 2010 @@ -8,7 +8,7 @@ import lldb import lldbtest -class TestClassTypes(lldbtest.TestBase): +class TestOrder(lldbtest.TestBase): mydir = "order" Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=109539&r1=109538&r2=109539&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Tue Jul 27 15:59:06 2010 @@ -5,11 +5,11 @@ import lldb import lldbtest -class TestClassTypes(lldbtest.TestBase): +class TestSetValues(lldbtest.TestBase): mydir = "set_values" - def test_class_types(self): + def test_set_values(self): """Test settings and readings of program variables.""" res = self.res exe = os.path.join(os.getcwd(), "a.out") From johnny.chen at apple.com Tue Jul 27 16:03:55 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Jul 2010 21:03:55 -0000 Subject: [Lldb-commits] [lldb] r109540 - in /lldb/trunk/test/order: TestOrder.py TestOrderFile.py Message-ID: <20100727210355.ABB3A2A6C12C@llvm.org> Author: johnny Date: Tue Jul 27 16:03:55 2010 New Revision: 109540 URL: http://llvm.org/viewvc/llvm-project?rev=109540&view=rev Log: Renaming from TestOrder.py to TestOrderFile.py. Added: lldb/trunk/test/order/TestOrderFile.py - copied, changed from r109539, lldb/trunk/test/order/TestOrder.py Removed: lldb/trunk/test/order/TestOrder.py Removed: lldb/trunk/test/order/TestOrder.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrder.py?rev=109539&view=auto ============================================================================== --- lldb/trunk/test/order/TestOrder.py (original) +++ lldb/trunk/test/order/TestOrder.py (removed) @@ -1,39 +0,0 @@ -""" -Test that debug symbols have the correct order as specified by the order file. -""" - -import os, time -import re -import unittest -import lldb -import lldbtest - -class TestOrder(lldbtest.TestBase): - - mydir = "order" - - def test_order(self): - """Test debug symbols follow the correct order by the order file.""" - res = self.res - exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) - - # Test that the debug symbols have Function f3 before Function f1. - self.ci.HandleCommand("image dump symtab a.out", res) - self.assertTrue(res.Succeeded()) - output = res.GetOutput() - mo_f3 = re.search("Function +.+f3", output) - mo_f1 = re.search("Function +.+f1", output) - - # Match objects for f3 and f1 must exist and f3 must come before f1. - self.assertTrue(mo_f3 and mo_f1 and mo_f3.start() < mo_f1.start()) - - self.ci.HandleCommand("run", res) - self.assertTrue(res.Succeeded()) - - -if __name__ == '__main__': - lldb.SBDebugger.Initialize() - unittest.main() - lldb.SBDebugger.Terminate() Copied: lldb/trunk/test/order/TestOrderFile.py (from r109539, lldb/trunk/test/order/TestOrder.py) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrderFile.py?p2=lldb/trunk/test/order/TestOrderFile.py&p1=lldb/trunk/test/order/TestOrder.py&r1=109539&r2=109540&rev=109540&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrder.py (original) +++ lldb/trunk/test/order/TestOrderFile.py Tue Jul 27 16:03:55 2010 @@ -8,11 +8,11 @@ import lldb import lldbtest -class TestOrder(lldbtest.TestBase): +class TestOrderFile(lldbtest.TestBase): mydir = "order" - def test_order(self): + def test_order_file(self): """Test debug symbols follow the correct order by the order file.""" res = self.res exe = os.path.join(os.getcwd(), "a.out") From scallanan at apple.com Tue Jul 27 16:39:39 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 27 Jul 2010 21:39:39 -0000 Subject: [Lldb-commits] [lldb] r109543 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp Message-ID: <20100727213940.115EB2A6C12C@llvm.org> Author: spyffe Date: Tue Jul 27 16:39:39 2010 New Revision: 109543 URL: http://llvm.org/viewvc/llvm-project?rev=109543&view=rev Log: Added support for calling functions from expressions. Right now we mock up the function as a variadic function when generating the IR for the call; we need to eventually make the function be the right type if the type is available. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=109543&r1=109542&r2=109543&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Tue Jul 27 16:39:39 2010 @@ -88,7 +88,9 @@ off_t &offset, uint32_t index); - uint64_t GetFunctionAddress (const clang::NamedDecl *decl); + bool GetFunctionInfo (const clang::NamedDecl *decl, + llvm::Value**& value, + uint64_t &ptr); // Interface for DwarfExpression Value *GetValueForIndex (uint32_t index); @@ -119,6 +121,7 @@ TypeFromParser m_parser_type; TypeFromUser m_user_type; lldb_private::Value *m_value; /* owned by ClangExpressionDeclMap */ + llvm::Value *m_llvm_value; }; struct StructMember Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=109543&r1=109542&r2=109543&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Jul 27 16:39:39 2010 @@ -182,8 +182,10 @@ return true; } -uint64_t -ClangExpressionDeclMap::GetFunctionAddress (const clang::NamedDecl *decl) +bool +ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl, + llvm::Value**& value, + uint64_t &ptr) { TupleIterator iter; @@ -193,11 +195,13 @@ { if (decl == iter->m_decl) { - return iter->m_value->GetScalar().ULongLong(); + value = &iter->m_llvm_value; + ptr = iter->m_value->GetScalar().ULongLong(); + return true; } } - return 0; + return false; } // Interface for DwarfExpression @@ -769,6 +773,7 @@ tuple.m_value = var_location; tuple.m_user_type = ut; tuple.m_parser_type = pt; + tuple.m_llvm_value = NULL; m_tuples.push_back(tuple); @@ -841,6 +846,7 @@ tuple.m_decl = fun_decl; tuple.m_value = fun_location.release(); tuple.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context); + tuple.m_llvm_value = NULL; m_tuples.push_back(tuple); Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=109543&r1=109542&r2=109543&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Tue Jul 27 16:39:39 2010 @@ -29,7 +29,7 @@ IRForTarget::IRForTarget(const void *pid, lldb_private::ClangExpressionDeclMap *decl_map, - const llvm::TargetData *target_data) : + const TargetData *target_data) : ModulePass(pid), m_decl_map(decl_map), m_target_data(target_data) @@ -41,8 +41,8 @@ } static clang::NamedDecl * -DeclForGlobalValue(llvm::Module &module, - llvm::GlobalValue *global_value) +DeclForGlobalValue(Module &module, + GlobalValue *global_value) { NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs"); @@ -82,7 +82,7 @@ bool IRForTarget::MaybeHandleVariable(Module &M, - llvm::Value *V, + Value *V, bool Store) { if (GlobalVariable *global_variable = dyn_cast(V)) @@ -104,7 +104,7 @@ return false; } - const llvm::Type *value_type = global_variable->getType(); + const Type *value_type = global_variable->getType(); size_t value_size = m_target_data->getTypeStoreSize(value_type); off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type); @@ -128,7 +128,7 @@ { lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - llvm::Function *fun = C->getCalledFunction(); + Function *fun = C->getCalledFunction(); if (fun == NULL) return true; @@ -142,9 +142,10 @@ return false; } - uint64_t fun_addr = m_decl_map->GetFunctionAddress(fun_decl); + uint64_t fun_addr; + Value **fun_value_ptr; - if (fun_addr == 0) + if (!m_decl_map->GetFunctionInfo(fun_decl, fun_value_ptr, fun_addr)) { if (log) log->Printf("Function %s had no address", fun_decl->getNameAsCString()); @@ -154,6 +155,22 @@ if (log) log->Printf("Found %s at %llx", fun_decl->getNameAsCString(), fun_addr); + if (!*fun_value_ptr) + { + std::vector params; + + const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(), + (M.getPointerSize() == Module::Pointer64) ? 64 : 32); + + FunctionType *fun_ty = FunctionType::get(intptr_ty, params, true); + PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); + Constant *fun_addr_int = ConstantInt::get(intptr_ty, fun_addr, false); + Constant *fun_addr_ptr = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); + *fun_value_ptr = fun_addr_ptr; + } + + C->setCalledFunction(*fun_value_ptr); + return true; } @@ -164,7 +181,7 @@ // Prepare the current basic block for execution in the remote process // - llvm::BasicBlock::iterator ii; + BasicBlock::iterator ii; for (ii = BB.begin(); ii != BB.end(); @@ -189,7 +206,7 @@ } static std::string -PrintValue(llvm::Value *V, bool truncate = false) +PrintValue(Value *V, bool truncate = false) { std::string s; raw_string_ostream rso(s); @@ -200,7 +217,7 @@ return s; } -static bool isGuardVariableRef(llvm::Value *V) +static bool isGuardVariableRef(Value *V) { ConstantExpr *C = dyn_cast(V); @@ -250,9 +267,9 @@ // Eliminate any reference to guard variables found. // - llvm::BasicBlock::iterator ii; + BasicBlock::iterator ii; - typedef llvm::SmallVector InstrList; + typedef SmallVector InstrList; typedef InstrList::iterator InstrIterator; InstrList guard_loads; @@ -300,7 +317,7 @@ // for those. static bool -UnfoldConstant(llvm::Constant *C, llvm::Value *new_value, llvm::Instruction *first_entry_instruction) +UnfoldConstant(Constant *C, Value *new_value, Instruction *first_entry_instruction) { lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); @@ -415,7 +432,7 @@ if (iter == F->getArgumentList().end()) return false; - llvm::Argument *argument = iter; + Argument *argument = iter; if (!argument->getName().equals("___clang_arg")) return false; @@ -423,8 +440,8 @@ if (log) log->Printf("Arg: %s", PrintValue(argument).c_str()); - llvm::BasicBlock &entry_block(F->getEntryBlock()); - llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg()); + BasicBlock &entry_block(F->getEntryBlock()); + Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg()); if (!first_entry_instruction) return false; @@ -438,7 +455,7 @@ for (element_index = 0; element_index < num_elements; ++element_index) { const clang::NamedDecl *decl; - llvm::Value *value; + Value *value; off_t offset; if (!m_decl_map->GetStructElement (decl, value, offset, element_index)) @@ -471,7 +488,7 @@ { lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - llvm::Function* function = M.getFunction(StringRef("___clang_expr")); + Function* function = M.getFunction(StringRef("___clang_expr")); if (!function) { @@ -481,7 +498,7 @@ return false; } - llvm::Function::iterator bbi; + Function::iterator bbi; for (bbi = function->begin(); bbi != function->end(); From johnny.chen at apple.com Tue Jul 27 16:49:20 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Jul 2010 21:49:20 -0000 Subject: [Lldb-commits] [lldb] r109545 - /lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Message-ID: <20100727214920.469852A6C12C@llvm.org> Author: johnny Date: Tue Jul 27 16:49:20 2010 New Revision: 109545 URL: http://llvm.org/viewvc/llvm-project?rev=109545&view=rev Log: Added a test case for showing variables of unsigned types. Added: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Added: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=109545&view=auto ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (added) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Tue Jul 27 16:49:20 2010 @@ -0,0 +1,72 @@ +""" +Test that variables with unsigned types display correctly. +""" + +import os, time +import re +import unittest +import lldb +import lldbtest + +class TestUnsignedTypes(lldbtest.TestBase): + + mydir = "unsigned_types" + + def test_unsigned_types(self): + """Test that variables with unsigned types display correctly.""" + res = self.res + exe = os.path.join(os.getcwd(), "a.out") + self.ci.HandleCommand("file " + exe, res) + self.assertTrue(res.Succeeded()) + + # Break on line 19 in main() aftre the variables are assigned values. + self.ci.HandleCommand("breakpoint set -f main.cpp -l 19", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().startswith( + "Breakpoint created: 1: file ='main.cpp', line = 19, locations = 1") + ) + + self.ci.HandleCommand("run", res) + time.sleep(0.1) + self.assertTrue(res.Succeeded()) + + # The stop reason of the thread should be breakpoint. + self.ci.HandleCommand("thread list", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and + res.GetOutput().find('stop reason = breakpoint') > 0) + + # The breakpoint should have a hit count of 1. + self.ci.HandleCommand("breakpoint list", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + + # Test that unsigned types display correctly. + self.ci.HandleCommand("variable list -a", res) + print "variable list -a ->", res.GetOutput() + self.assertTrue(res.Succeeded()) + output = res.GetOutput() + self.assertTrue( + output.startswith("the_unsigned_char = (unsigned char) 'c'") + and + output.find("the_unsigned_short = (short unsigned int) 0x0063") > 0 + and + output.find("the_unsigned_int = (unsigned int) 0x00000063") > 0 + and + output.find("the_unsigned_long = (long unsigned int) " + "0x0000000000000063") > 0 + and + output.find("the_unsigned_long_long = (long long unsigned int)" + " 0x0000000000000063") > 0 + and + output.find("the_uint32 = (uint32_t) 0x00000063") + ) + + self.ci.HandleCommand("continue", res) + self.assertTrue(res.Succeeded()) + + +if __name__ == '__main__': + lldb.SBDebugger.Initialize() + unittest.main() + lldb.SBDebugger.Terminate() From johnny.chen at apple.com Tue Jul 27 17:48:46 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 27 Jul 2010 22:48:46 -0000 Subject: [Lldb-commits] [lldb] r109552 - /lldb/trunk/test/struct_types/TestStructTypes.py Message-ID: <20100727224846.4F2752A6C12C@llvm.org> Author: johnny Date: Tue Jul 27 17:48:46 2010 New Revision: 109552 URL: http://llvm.org/viewvc/llvm-project?rev=109552&view=rev Log: Added a test case to test that break on a struct declaration has no effect. Instead, the first executable statement is set as the breakpoint. Added: lldb/trunk/test/struct_types/TestStructTypes.py Added: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=109552&view=auto ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (added) +++ lldb/trunk/test/struct_types/TestStructTypes.py Tue Jul 27 17:48:46 2010 @@ -0,0 +1,54 @@ +""" +Test that break on a struct declaration has no effect. + +Instead, the first executable statement is set as the breakpoint. +""" + +import os, time +import unittest +import lldb +import lldbtest + +class TestStructTypes(lldbtest.TestBase): + + mydir = "struct_types" + + def test_struct_types(self): + """Test that break on a struct declaration has no effect.""" + res = self.res + exe = os.path.join(os.getcwd(), "a.out") + self.ci.HandleCommand("file " + exe, res) + self.assertTrue(res.Succeeded()) + + # Break on the ctor function of class C. + self.ci.HandleCommand("breakpoint set -f main.c -l 14", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().startswith( + "Breakpoint created: 1: file ='main.c', line = 14, locations = 1")) + + self.ci.HandleCommand("run", res) + time.sleep(0.1) + self.assertTrue(res.Succeeded()) + + # We should be stopped on the first executable statement within the + # function where the original breakpoint was attempted. + self.ci.HandleCommand("thread backtrace", res) + print "thread backtrace ->", res.GetOutput() + self.assertTrue(res.Succeeded()) + output = res.GetOutput() + self.assertTrue(output.find('main.c:20') > 0 and + output.find('stop reason = breakpoint') > 0) + + # The breakpoint should have a hit count of 1. + self.ci.HandleCommand("breakpoint list", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + + self.ci.HandleCommand("continue", res) + self.assertTrue(res.Succeeded()) + + +if __name__ == '__main__': + lldb.SBDebugger.Initialize() + unittest.main() + lldb.SBDebugger.Terminate() From scallanan at apple.com Tue Jul 27 20:00:59 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 28 Jul 2010 01:00:59 -0000 Subject: [Lldb-commits] [lldb] r109568 - in /lldb/trunk: include/lldb/Expression/RecordingMemoryManager.h source/Expression/ClangExpression.cpp source/Expression/IRForTarget.cpp source/Expression/IRToDWARF.cpp source/Expression/RecordingMemoryManager.cpp Message-ID: <20100728010059.A96D42A6C12C@llvm.org> Author: spyffe Date: Tue Jul 27 20:00:59 2010 New Revision: 109568 URL: http://llvm.org/viewvc/llvm-project?rev=109568&view=rev Log: Added and improved logging. This is helping us as we diagnose a problem where we're not correctly emitting PIC code. Modified: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h lldb/trunk/source/Expression/ClangExpression.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Expression/IRToDWARF.cpp lldb/trunk/source/Expression/RecordingMemoryManager.cpp Modified: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h?rev=109568&r1=109567&r2=109568&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (original) +++ lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h Tue Jul 27 20:00:59 2010 @@ -21,6 +21,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" +#include "lldb/Core/Log.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "lldb/Expression/ClangExpression.h" @@ -128,6 +129,8 @@ std::map m_stubs; std::map m_globals; std::map m_exception_tables; + + lldb_private::Log *m_log; struct LocalToRemoteAddressRange { Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=109568&r1=109567&r2=109568&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Tue Jul 27 20:00:59 2010 @@ -527,6 +527,7 @@ bool ClangExpression::JITFunction (const ExecutionContext &exc_context, const char *name) { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); llvm::Module *module = m_code_generator_ptr->GetModule(); @@ -538,11 +539,41 @@ m_jit_mm_ptr = new RecordingMemoryManager(); //llvm::InitializeNativeTarget(); + if (m_execution_engine.get() == 0) - m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, &error, m_jit_mm_ptr)); + m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, + &error, + m_jit_mm_ptr, + CodeGenOpt::Default, + true, + CodeModel::Default)); + m_execution_engine->DisableLazyCompilation(); llvm::Function *function = module->getFunction (llvm::StringRef (name)); - + + if (log) + { + const char *relocation_model_string; + + switch (llvm::TargetMachine::getRelocationModel()) + { + case llvm::Reloc::Default: + relocation_model_string = "Default"; + break; + case llvm::Reloc::Static: + relocation_model_string = "Static"; + break; + case llvm::Reloc::PIC_: + relocation_model_string = "PIC_++"; + break; + case llvm::Reloc::DynamicNoPIC: + relocation_model_string = "DynamicNoPIC"; + break; + } + + log->Printf("Target machine's relocation model: %s", relocation_model_string); + } + // We don't actually need the function pointer here, this just forces it to get resolved. void *fun_ptr = m_execution_engine->getPointerToFunction(function); // Note, you probably won't get here on error, since the LLVM JIT tends to just @@ -558,6 +589,8 @@ bool ClangExpression::WriteJITCode (const ExecutionContext &exc_context) { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + if (m_jit_mm_ptr == NULL) return false; @@ -586,6 +619,9 @@ lldb::addr_t cursor = target_addr; for (fun_pos = m_jit_mm_ptr->m_functions.begin(); fun_pos != fun_end; fun_pos++) { + if (log) + log->Printf("Reading [%p-%p] from m_functions", fun_pos->first, fun_pos->second); + lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first; lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second; size_t size = lend - lstart; Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=109568&r1=109567&r2=109568&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Tue Jul 27 20:00:59 2010 @@ -511,20 +511,22 @@ return false; } + // TEMPORARY FOR DEBUGGING + M.dump(); + if (!replaceVariables(M, function)) return false; if (log) { - for (bbi = function->begin(); - bbi != function->end(); - ++bbi) - { - log->Printf("Rewrote basic block %s for running: \n%s", - bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]", - PrintValue(bbi).c_str()); - } + std::string s; + raw_string_ostream oss(s); + + M.print(oss, NULL); + + oss.flush(); + log->Printf("Module after preparing for execution: \n%s", s.c_str()); } return true; Modified: lldb/trunk/source/Expression/IRToDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRToDWARF.cpp?rev=109568&r1=109567&r2=109568&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRToDWARF.cpp (original) +++ lldb/trunk/source/Expression/IRToDWARF.cpp Tue Jul 27 20:00:59 2010 @@ -119,9 +119,7 @@ bool IRToDWARF::runOnBasicBlock(BasicBlock &BB, Relocator &R) -{ - lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - +{ /////////////////////////////////////// // Mark the current block as visited // @@ -139,29 +137,6 @@ // Translate the current basic block to DWARF // - if (log) - { - log->Printf("Translating basic block %s:", - BB.hasName() ? BB.getNameStr().c_str() : "[anonymous]"); - - llvm::BasicBlock::iterator ii; - - for (ii = BB.begin(); - ii != BB.end(); - ++ii) - { - llvm::Instruction &inst = *ii; - - std::string s; - raw_string_ostream os(s); - - inst.print(os); - - if (log) - log->Printf(" %s", s.c_str()); - } - } - ///////////////////////////////////////////////// // Visit all successors we haven't visited yet // @@ -210,6 +185,18 @@ if (!runOnBasicBlock(function->getEntryBlock(), relocator)) return false; + if (log) + { + std::string s; + raw_string_ostream oss(s); + + M.print(oss, NULL); + + oss.flush(); + + log->Printf("Module being translated to DWARF: \n%s", s.c_str()); + } + // TEMPORARY: Fail in order to force execution in the target. return false; Modified: lldb/trunk/source/Expression/RecordingMemoryManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/RecordingMemoryManager.cpp?rev=109568&r1=109567&r2=109568&view=diff ============================================================================== --- lldb/trunk/source/Expression/RecordingMemoryManager.cpp (original) +++ lldb/trunk/source/Expression/RecordingMemoryManager.cpp Tue Jul 27 20:00:59 2010 @@ -19,6 +19,7 @@ llvm::JITMemoryManager(), m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()) { + m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); } RecordingMemoryManager::~RecordingMemoryManager () @@ -60,6 +61,9 @@ uint8_t *FunctionEnd) { m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd); + if (m_log) + m_log->Printf("Adding [%p-%p] to m_functions", + FunctionStart, FunctionEnd); m_functions.insert(std::pair(FunctionStart, FunctionEnd)); } @@ -67,6 +71,9 @@ RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) { uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment); + if (m_log) + m_log->Printf("RecordingMemoryManager::allocateSpace(Size=0x%llx, Alignment=%u) = %p", + (uint64_t)Size, Alignment, return_value); m_spaceBlocks.insert (std::pair(return_value, Size)); return return_value; } @@ -75,6 +82,9 @@ RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) { uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment); + if (m_log) + m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%llx, Alignment=%u) = %p", + (uint64_t)Size, Alignment, return_value); m_globals.insert (std::pair(return_value, Size)); return return_value; } @@ -144,6 +154,9 @@ void RecordingMemoryManager::AddToLocalToRemoteMap (lldb::addr_t lstart, size_t size, lldb::addr_t rstart) { + if (m_log) + m_log->Printf("Adding local [0x%llx-0x%llx], remote [0x%llx-0x%llx] to local->remote map", lstart, lstart + size, rstart, rstart + size); + m_address_map.push_back (LocalToRemoteAddressRange(lstart, size, rstart)); } From gclayton at apple.com Tue Jul 27 21:04:10 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 28 Jul 2010 02:04:10 -0000 Subject: [Lldb-commits] [lldb] r109574 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Symbol/ source/Commands/ source/Core/ source/Plugins/SymbolFile/DWARF/ source/Plugins/SymbolFile/Symtab/ source/Symbol/ Message-ID: <20100728020410.36D412A6C12C@llvm.org> Author: gclayton Date: Tue Jul 27 21:04:09 2010 New Revision: 109574 URL: http://llvm.org/viewvc/llvm-project?rev=109574&view=rev Log: Created lldb::LanguageType by moving an enumeration from the lldb_private::Language class into the enumerations header so it can be freely used by other interfaces. Added correct objective C class support to the DWARF symbol parser. Prior to this fix we were parsing objective C classes as C++ classes and now that the expression parser is ready to call functions we need to make sure the objective C classes have correct AST types. Modified: lldb/trunk/include/lldb/Core/Language.h lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/include/lldb/Symbol/CompileUnit.h lldb/trunk/include/lldb/Symbol/SymbolContext.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Core/Language.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Symbol/ClangASTType.cpp lldb/trunk/source/Symbol/CompileUnit.cpp lldb/trunk/source/Symbol/Type.cpp Modified: lldb/trunk/include/lldb/Core/Language.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Language.h?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Language.h (original) +++ lldb/trunk/include/lldb/Core/Language.h Tue Jul 27 21:04:09 2010 @@ -26,42 +26,10 @@ class Language { public: - - //------------------------------------------------------------------ - /// Programming language type. - /// - /// These enumerations use the same language enumerations as the - /// DWARF specification for ease of use and consistency. - //------------------------------------------------------------------ - typedef enum - { - Unknown = 0x0000, ///< Unknown or invalid language value. - C89 = 0x0001, ///< ISO C:1989. - C = 0x0002, ///< Non-standardized C, such as K&R. - Ada83 = 0x0003, ///< ISO Ada:1983. - C_plus_plus = 0x0004, ///< ISO C++:1998. - Cobol74 = 0x0005, ///< ISO Cobol:1974. - Cobol85 = 0x0006, ///< ISO Cobol:1985. - Fortran77 = 0x0007, ///< ISO Fortran 77. - Fortran90 = 0x0008, ///< ISO Fortran 90. - Pascal83 = 0x0009, ///< ISO Pascal:1983. - Modula2 = 0x000a, ///< ISO Modula-2:1996. - Java = 0x000b, ///< Java. - C99 = 0x000c, ///< ISO C:1999. - Ada95 = 0x000d, ///< ISO Ada:1995. - Fortran95 = 0x000e, ///< ISO Fortran 95. - PLI = 0x000f, ///< ANSI PL/I:1976. - ObjC = 0x0010, ///< Objective-C. - ObjC_plus_plus = 0x0011, ///< Objective-C++. - UPC = 0x0012, ///< Unified Parallel C. - D = 0x0013, ///< D. - Python = 0x0014 ///< Python. - } Type; - //------------------------------------------------------------------ /// Construct with optional language enumeration. //------------------------------------------------------------------ - Language(Language::Type language = Unknown); + Language(lldb::LanguageType language = lldb::eLanguageTypeUnknown); //------------------------------------------------------------------ /// Destructor. @@ -78,7 +46,7 @@ /// The C string representation of the language. The returned /// string does not need to be freed as it comes from constant /// strings. NULL can be returned when the language is set to - /// a value that doesn't match of of the Language::Type + /// a value that doesn't match of of the lldb::LanguageType /// enumerations. //------------------------------------------------------------------ const char * @@ -106,7 +74,7 @@ /// The enumeration value that describes the programming /// language that an object is associated with. //------------------------------------------------------------------ - Language::Type + lldb::LanguageType GetLanguage() const; //------------------------------------------------------------------ @@ -117,7 +85,7 @@ /// language that an object is associated with. //------------------------------------------------------------------ void - SetLanguage(Language::Type language); + SetLanguage(lldb::LanguageType language); //------------------------------------------------------------------ /// Set accessor for the language. @@ -133,9 +101,9 @@ //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ - Language::Type m_language; ///< The programming language enumeration value. - ///< The enumeration values are the same as the - ///< latest DWARF specification. + lldb::LanguageType m_language; ///< The programming language enumeration value. + ///< The enumeration values are the same as the + ///< latest DWARF specification. }; //-------------------------------------------------------------- Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Jul 27 21:04:09 2010 @@ -157,7 +157,8 @@ void * CreateRecordType (const char *name, int kind, - clang::DeclContext *decl_ctx); + clang::DeclContext *decl_ctx, + lldb::LanguageType language); bool AddFieldToRecordType (void * record_qual_type, @@ -201,6 +202,14 @@ bool SetObjCSuperClass (void *class_clang_type, void *superclass_clang_type); + + static bool + ObjCTypeHasIVars (void *class_clang_type, bool check_superclass); + + static bool + ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl, + bool check_superclass); + //------------------------------------------------------------------ // Aggregate Types Modified: lldb/trunk/include/lldb/Symbol/CompileUnit.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CompileUnit.h?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/CompileUnit.h (original) +++ lldb/trunk/include/lldb/Symbol/CompileUnit.h Tue Jul 27 21:04:09 2010 @@ -66,9 +66,9 @@ /// A language enumeration type that describes the main language /// of this compile unit. /// - /// @see Language::Type + /// @see lldb::LanguageType //------------------------------------------------------------------ - CompileUnit(Module *module, void *user_data, const char *pathname, lldb::user_id_t uid, Language::Type language); + CompileUnit(Module *module, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language); //------------------------------------------------------------------ /// Construct with a module, file spec, UID and language. @@ -98,9 +98,9 @@ /// A language enumeration type that describes the main language /// of this compile unit. /// - /// @see Language::Type + /// @see lldb::LanguageType //------------------------------------------------------------------ - CompileUnit(Module *module, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, Language::Type language); + CompileUnit(Module *module, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language); //------------------------------------------------------------------ /// Destructor Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Tue Jul 27 21:04:09 2010 @@ -225,7 +225,7 @@ //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ - lldb::TargetSP target_sp; ///< The Target for a given query + lldb::TargetSP target_sp; ///< The Target for a given query lldb::ModuleSP module_sp; ///< The Module for a given query CompileUnit * comp_unit; ///< The CompileUnit for a given query Function * function; ///< The Function for a given query Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Jul 27 21:04:09 2010 @@ -428,6 +428,38 @@ } BreakpointEventType; +//---------------------------------------------------------------------- +/// Programming language type. +/// +/// These enumerations use the same language enumerations as the DWARF +/// specification for ease of use and consistency. +//---------------------------------------------------------------------- +typedef enum LanguageType +{ + eLanguageTypeUnknown = 0x0000, ///< Unknown or invalid language value. + eLanguageTypeC89 = 0x0001, ///< ISO C:1989. + eLanguageTypeC = 0x0002, ///< Non-standardized C, such as K&R. + eLanguageTypeAda83 = 0x0003, ///< ISO Ada:1983. + eLanguageTypeC_plus_plus = 0x0004, ///< ISO C++:1998. + eLanguageTypeCobol74 = 0x0005, ///< ISO Cobol:1974. + eLanguageTypeCobol85 = 0x0006, ///< ISO Cobol:1985. + eLanguageTypeFortran77 = 0x0007, ///< ISO Fortran 77. + eLanguageTypeFortran90 = 0x0008, ///< ISO Fortran 90. + eLanguageTypePascal83 = 0x0009, ///< ISO Pascal:1983. + eLanguageTypeModula2 = 0x000a, ///< ISO Modula-2:1996. + eLanguageTypeJava = 0x000b, ///< Java. + eLanguageTypeC99 = 0x000c, ///< ISO C:1999. + eLanguageTypeAda95 = 0x000d, ///< ISO Ada:1995. + eLanguageTypeFortran95 = 0x000e, ///< ISO Fortran 95. + eLanguageTypePLI = 0x000f, ///< ANSI PL/I:1976. + eLanguageTypeObjC = 0x0010, ///< Objective-C. + eLanguageTypeObjC_plus_plus = 0x0011, ///< Objective-C++. + eLanguageTypeUPC = 0x0012, ///< Unified Parallel C. + eLanguageTypeD = 0x0013, ///< D. + eLanguageTypePython = 0x0014 ///< Python. +} LanguageType; + + } // namespace lldb Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Tue Jul 27 21:04:09 2010 @@ -146,21 +146,21 @@ "'alias' allows the user to create a short-cut or abbreviation for long \n\ commands, multi-word commands, and commands that take particular options. \n\ Below are some simple examples of how one might use the 'alias' command: \n\ - \n 'alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ + \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ // command. \n\ - 'alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ + 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ // command. Since breakpoint commands are two-word \n\ // commands, the user will still need to enter the \n\ // second word after 'bp', e.g. 'bp enable' or \n\ // 'bp delete'. \n\ - 'alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\ + 'command alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\ // two-word command 'breakpoint list'. \n\ \nAn alias can include some options for the command, with the values either \n\ filled in at the time the alias is created, or specified as positional \n\ arguments, to be filled in when the alias is invoked. The following example \n\ shows how to create aliases with options: \n\ \n\ - 'alias bfl breakpoint set -f %1 -l %2' \n\ + 'command alias bfl breakpoint set -f %1 -l %2' \n\ \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ options already part of the alias. So if the user wants to set a breakpoint \n\ by file and line without explicitly having to use the -f and -l options, the \n\ Modified: lldb/trunk/source/Core/Language.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Language.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Core/Language.cpp (original) +++ lldb/trunk/source/Core/Language.cpp Tue Jul 27 21:04:09 2010 @@ -51,7 +51,7 @@ static const size_t g_num_languages = sizeof(g_languages)/sizeof(LanguageStrings); -Language::Language(Language::Type language) : +Language::Language(LanguageType language) : m_language (language) { } @@ -60,7 +60,7 @@ { } -Language::Type +LanguageType Language::GetLanguage() const { return m_language; @@ -69,11 +69,11 @@ void Language::Clear () { - m_language = Unknown; + m_language = eLanguageTypeUnknown; } void -Language::SetLanguage(Language::Type language) +Language::SetLanguage(LanguageType language) { m_language = language; } @@ -95,13 +95,13 @@ if (::strcasecmp (language_cstr, name) == 0) { - m_language = (Language::Type)i; + m_language = (LanguageType)i; return true; } } } - m_language = Unknown; + m_language = eLanguageTypeUnknown; return false; } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Jul 27 21:04:09 2010 @@ -644,12 +644,12 @@ { const char * cu_die_name = cu_die->GetName(this, cu); const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL); - Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0); + LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0); if (cu_die_name) { if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0]) { - compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language)); + compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), class_language)); } else { @@ -658,7 +658,7 @@ fullpath += '/'; fullpath += cu_die_name; - compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language)); + compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), class_language)); } if (compile_unit_sp.get()) @@ -1211,6 +1211,8 @@ TypeSP& type_sp, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *parent_die, + void *class_clang_type, + const LanguageType class_language, std::vector& base_classes, std::vector& member_accessibilities, ClangASTContext::AccessType& default_accessibility, @@ -1376,8 +1378,16 @@ Type *base_class_dctype = ResolveTypeUID(encoding_uid); assert(base_class_dctype); - base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class)); - assert(base_classes.back()); + + if (class_language == eLanguageTypeObjC) + { + type_list->GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetOpaqueClangQualType()); + } + else + { + base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class)); + assert(base_classes.back()); + } } } break; @@ -2707,6 +2717,7 @@ const_cast(die)->SetUserData(DIE_IS_BEING_PARSED); size_t byte_size = 0; + LanguageType class_language = eLanguageTypeUnknown; //bool struct_is_class = false; Declaration decl; const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes); @@ -2721,16 +2732,39 @@ { switch (attr) { - case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; - case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; - case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; + case DW_AT_decl_file: + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); + break; + + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_name: type_name_cstr = form_value.AsCString(&get_debug_str_data()); type_name_dbstr.SetCString(type_name_cstr); break; - case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; - case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; break; - case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; + + case DW_AT_byte_size: + byte_size = form_value.Unsigned(); + break; + + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; + + case DW_AT_declaration: + is_forward_declaration = form_value.Unsigned() != 0; + break; + + case DW_AT_APPLE_runtime_class: + class_language = (LanguageType)form_value.Signed(); + break; + case DW_AT_allocated: case DW_AT_associated: case DW_AT_data_location: @@ -2764,7 +2798,7 @@ } assert (tag_decl_kind != -1); - clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die)); + clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die), class_language); m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type)); @@ -2781,11 +2815,24 @@ std::vector base_classes; std::vector member_accessibilities; bool is_a_class = false; - ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class); + ParseChildMembers (sc, + type_sp, + dwarf_cu, + die, + clang_type, + class_language, + base_classes, + member_accessibilities, + default_accessibility, + is_a_class); + // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we // need to tell the clang type it is actually a class. - if (is_a_class && tag_decl_kind != clang::TTK_Class) - type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class); + if (class_language != eLanguageTypeObjC) + { + if (is_a_class && tag_decl_kind != clang::TTK_Class) + type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class); + } // Since DW_TAG_structure_type gets used for both classes // and structures, we may need to set any DW_TAG_member Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Tue Jul 27 21:04:09 2010 @@ -249,6 +249,8 @@ lldb::TypeSP& type_sp, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, + void *class_clang_type, + const lldb::LanguageType class_language, std::vector& base_classes, std::vector& member_accessibilities, lldb_private::ClangASTContext::AccessType &default_accessibility, Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Tue Jul 27 21:04:09 2010 @@ -495,7 +495,7 @@ NULL, so_symbol->GetMangled().GetName().AsCString(), cu_idx, - Language::Unknown)); + eLanguageTypeUnknown)); } } } Modified: lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp Tue Jul 27 21:04:09 2010 @@ -140,14 +140,14 @@ { const FileSpec &obj_file_spec = m_obj_file->GetFileSpec(); if (obj_file_spec) - cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, Language::Unknown)); + cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown)); } else if (idx < m_source_indexes.size()) { const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); if (cu_symbol) - cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, Language::Unknown)); + cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown)); } return cu_sp; } Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Jul 27 21:04:09 2010 @@ -753,7 +753,7 @@ #pragma mark Structure, Unions, Classes void * -ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx) +ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, lldb::LanguageType language) { ASTContext *ast_context = getASTContext(); assert (ast_context != NULL); @@ -761,6 +761,14 @@ if (decl_ctx == NULL) decl_ctx = ast_context->getTranslationUnitDecl(); + + if (language == lldb::eLanguageTypeObjC) + { + bool isForwardDecl = false; + bool isInternal = false; + return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal); + } + // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and // we will need to update this code. I was told to currently always use // the CXXRecordDecl class since we often don't know from debug information @@ -832,6 +840,20 @@ return true; } } + else + { + ObjCObjectType *objc_class_type = dyn_cast(clang_type); + if (objc_class_type) + { + bool isSynthesized = false; + ClangASTContext::AddObjCClassIVar (record_clang_type, + name, + field_type, + access, + bitfield_bit_size, + isSynthesized); + } + } } return false; } @@ -998,8 +1020,8 @@ SourceLocation(), isForwardDecl, isInternal); - - return QualType (decl->getTypeForDecl(), 0).getAsOpaquePtr(); + + return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr(); } bool @@ -1071,27 +1093,61 @@ bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); } - //ObjCIvarDecl *field = - ObjCIvarDecl::Create (*ast_context, - class_interface_decl, - SourceLocation(), - &identifier_table->get(name), // Identifier - QualType::getFromOpaquePtr(ivar_opaque_type), // Field type - NULL, // TypeSourceInfo * - ConvertAccessTypeToObjCIvarAccessControl (access), - bit_width, - isSynthesized); - // TODO: Do I need to do an addDecl? I am thinking I don't since - // I passed the "class_interface_decl" into "ObjCIvarDecl::Create" - // above. Verify this. Also verify it is ok to pass NULL TypeSourceInfo - // above. - return true; + ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context, + class_interface_decl, + SourceLocation(), + &identifier_table->get(name), // Identifier + QualType::getFromOpaquePtr(ivar_opaque_type), // Field type + NULL, // TypeSourceInfo * + ConvertAccessTypeToObjCIvarAccessControl (access), + bit_width, + isSynthesized); + + if (field) + { + class_interface_decl->addDecl(field); + return true; + } } } } return false; } + +bool +ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass) +{ + QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); + + clang::Type *class_type = class_qual_type.getTypePtr(); + if (class_type) + { + ObjCObjectType *objc_class_type = dyn_cast(class_type); + + if (objc_class_type) + return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); + } + return false; +} + +bool +ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) +{ + while (class_interface_decl) + { + if (class_interface_decl->ivar_size() > 0) + return true; + + if (check_superclass) + class_interface_decl = class_interface_decl->getSuperClass(); + else + break; + } + return false; +} + + #pragma mark Aggregate Types bool @@ -1113,6 +1169,9 @@ case clang::Type::ExtVector: case clang::Type::Vector: case clang::Type::Record: + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + case clang::Type::ObjCObjectPointer: return true; case clang::Type::Typedef: @@ -1133,7 +1192,8 @@ uint32_t num_children = 0; QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); - switch (qual_type->getTypeClass()) + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { case clang::Type::Record: { @@ -1176,6 +1236,40 @@ } break; + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + ObjCObjectType *objc_class_type = dyn_cast(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (omit_empty_base_classes) + { + if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) + ++num_children; + } + else + ++num_children; + } + + num_children += class_interface_decl->ivar_size(); + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + return ClangASTContext::GetNumChildren (cast(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), + omit_empty_base_classes); + case clang::Type::ConstantArray: num_children = cast(qual_type.getTypePtr())->getSize().getLimitedValue(); break; @@ -1184,7 +1278,8 @@ { PointerType *pointer_type = cast(qual_type.getTypePtr()); QualType pointee_type = pointer_type->getPointeeType(); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), omit_empty_base_classes); + uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), + omit_empty_base_classes); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -1349,6 +1444,100 @@ } break; + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + ObjCObjectType *objc_class_type = dyn_cast(parent_qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + uint32_t child_idx = 0; + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + + const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl); + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (omit_empty_base_classes) + { + if (ClangASTContext::GetNumChildren(superclass_interface_decl, omit_empty_base_classes) > 0) + { + if (idx == 0) + { + QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl)); + + + child_name.assign(superclass_interface_decl->getNameAsString().c_str()); + + std::pair ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); + + child_byte_size = ivar_type_info.first / 8; + + // Figure out the field offset within the current struct/union/class type + bit_offset = interface_layout.getFieldOffset (child_idx); + child_byte_offset = bit_offset / 8; + + return ivar_qual_type.getAsOpaquePtr(); + } + + ++child_idx; + } + } + else + ++child_idx; + } + + if (idx < (child_idx + class_interface_decl->ivar_size())) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) + { + if (child_idx == idx) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + QualType ivar_qual_type(ivar_decl->getType()); + + child_name.assign(ivar_decl->getNameAsString().c_str()); + + std::pair ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); + + child_byte_size = ivar_type_info.first / 8; + + // Figure out the field offset within the current struct/union/class type + bit_offset = interface_layout.getFieldOffset (child_idx); + child_byte_offset = bit_offset / 8; + + return ivar_qual_type.getAsOpaquePtr(); + } + ++child_idx; + } + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + { + return GetChildClangTypeAtIndex (ast_context, + parent_name, + cast(parent_qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), + idx, + transparent_pointers, + omit_empty_base_classes, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset); + } + break; + case clang::Type::ConstantArray: { const ConstantArrayType *array = cast(parent_qual_type.getTypePtr()); @@ -1707,6 +1896,76 @@ } break; + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + StringRef name_sref(name); + ObjCObjectType *objc_class_type = dyn_cast(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + uint32_t child_idx = 0; + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + if (ivar_decl->getName().equals (name_sref)) + { + if ((!omit_empty_base_classes && superclass_interface_decl) || + ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) + ++child_idx; + + child_indexes.push_back (child_idx); + return child_indexes.size(); + } + } + + if (superclass_interface_decl) + { + // The super class index is always zero for ObjC classes, + // so we push it onto the child indexes in case we find + // an ivar in our superclass... + child_indexes.push_back (0); + + if (GetIndexOfChildMemberWithName (ast_context, + ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), + name, + omit_empty_base_classes, + child_indexes)) + { + // We did find an ivar in a superclass so just + // return the results! + return child_indexes.size(); + } + + // We didn't find an ivar matching "name" in our + // superclass, pop the superclass zero index that + // we pushed on above. + child_indexes.pop_back(); + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + { + return GetIndexOfChildMemberWithName (ast_context, + cast(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), + name, + omit_empty_base_classes, + child_indexes); + } + break; + + case clang::Type::ConstantArray: { // const ConstantArrayType *array = cast(parent_qual_type.getTypePtr()); @@ -1824,7 +2083,10 @@ if (clang_type && name && name[0]) { QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - switch (qual_type->getTypeClass()) + + clang::Type::TypeClass qual_type_class = qual_type->getTypeClass(); + + switch (qual_type_class) { case clang::Type::Record: { @@ -1868,6 +2130,55 @@ } break; + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + StringRef name_sref(name); + ObjCObjectType *objc_class_type = dyn_cast(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + uint32_t child_idx = 0; + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + if (ivar_decl->getName().equals (name_sref)) + { + if ((!omit_empty_base_classes && superclass_interface_decl) || + ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) + ++child_idx; + + return child_idx; + } + } + + if (superclass_interface_decl) + { + if (superclass_interface_decl->getName().equals (name_sref)) + return 0; + } + } + } + } + break; + + case clang::Type::ObjCObjectPointer: + { + return GetIndexOfChildWithName (ast_context, + cast(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), + name, + omit_empty_base_classes); + } + break; + case clang::Type::ConstantArray: { // const ConstantArrayType *array = cast(parent_qual_type.getTypePtr()); @@ -2003,34 +2314,32 @@ QualType qual_type(QualType::getFromOpaquePtr(clang_type)); switch (qual_type->getTypeClass()) { - case clang::Type::FunctionNoProto: break; - case clang::Type::FunctionProto: break; - case clang::Type::IncompleteArray: break; - case clang::Type::VariableArray: break; - case clang::Type::ConstantArray: break; - case clang::Type::ExtVector: break; - case clang::Type::Vector: break; - case clang::Type::Builtin: break; - case clang::Type::ObjCObjectPointer: break; - case clang::Type::BlockPointer: break; - case clang::Type::Pointer: break; - case clang::Type::LValueReference: break; - case clang::Type::RValueReference: break; - case clang::Type::MemberPointer: break; - case clang::Type::Complex: break; - case clang::Type::ObjCInterface: break; - case clang::Type::Record: - return cast(qual_type)->getDecl(); - case clang::Type::Enum: - return cast(qual_type)->getDecl(); - case clang::Type::Typedef: - return ClangASTContext::GetDeclContextForType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); - - case clang::Type::TypeOfExpr: break; - case clang::Type::TypeOf: break; - case clang::Type::Decltype: break; - //case clang::Type::QualifiedName: break; - case clang::Type::TemplateSpecialization: break; + case clang::Type::FunctionNoProto: break; + case clang::Type::FunctionProto: break; + case clang::Type::IncompleteArray: break; + case clang::Type::VariableArray: break; + case clang::Type::ConstantArray: break; + case clang::Type::ExtVector: break; + case clang::Type::Vector: break; + case clang::Type::Builtin: break; + case clang::Type::BlockPointer: break; + case clang::Type::Pointer: break; + case clang::Type::LValueReference: break; + case clang::Type::RValueReference: break; + case clang::Type::MemberPointer: break; + case clang::Type::Complex: break; + case clang::Type::ObjCObject: break; + case clang::Type::ObjCInterface: return cast(qual_type.getTypePtr())->getInterface(); + case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); + case clang::Type::Record: return cast(qual_type)->getDecl(); + case clang::Type::Enum: return cast(qual_type)->getDecl(); + case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); + + case clang::Type::TypeOfExpr: break; + case clang::Type::TypeOf: break; + case clang::Type::Decltype: break; + //case clang::Type::QualifiedName: break; + case clang::Type::TemplateSpecialization: break; } // No DeclContext in this type... return NULL; Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Tue Jul 27 21:04:09 2010 @@ -614,7 +614,8 @@ } else { - switch (qual_type->getTypeClass()) + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) { case clang::Type::Enum: { Modified: lldb/trunk/source/Symbol/CompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompileUnit.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Symbol/CompileUnit.cpp (original) +++ lldb/trunk/source/Symbol/CompileUnit.cpp Tue Jul 27 21:04:09 2010 @@ -16,7 +16,7 @@ using namespace lldb; using namespace lldb_private; -CompileUnit::CompileUnit (Module *module, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, Language::Type language) : +CompileUnit::CompileUnit (Module *module, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) : ModuleChild(module), FileSpec (pathname), UserID(cu_sym_id), @@ -31,7 +31,7 @@ assert(module != NULL); } -CompileUnit::CompileUnit (Module *module, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, Language::Type language) : +CompileUnit::CompileUnit (Module *module, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) : ModuleChild(module), FileSpec (fspec), UserID(cu_sym_id), Modified: lldb/trunk/source/Symbol/Type.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=109574&r1=109573&r2=109574&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Type.cpp (original) +++ lldb/trunk/source/Symbol/Type.cpp Tue Jul 27 21:04:09 2010 @@ -219,7 +219,7 @@ const clang::TypedefDecl *typedef_decl = typedef_type->getDecl(); std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString()); if (!clang_typedef_name.empty()) - *s << " (" << clang_typedef_name.c_str() << ')'; + *s << '(' << clang_typedef_name.c_str() << ')'; } else { @@ -229,7 +229,7 @@ { std::string clang_type_name(qual_type.getAsString()); if (!clang_type_name.empty()) - *s << " (" << clang_type_name.c_str() << ')'; + *s << '(' << clang_type_name.c_str() << ')'; } } } From johnny.chen at apple.com Wed Jul 28 16:16:11 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 28 Jul 2010 21:16:11 -0000 Subject: [Lldb-commits] [lldb] r109673 - in /lldb/trunk: source/Interpreter/CommandInterpreter.cpp tools/driver/Driver.cpp Message-ID: <20100728211611.53CC62A6C12C@llvm.org> Author: johnny Date: Wed Jul 28 16:16:11 2010 New Revision: 109673 URL: http://llvm.org/viewvc/llvm-project?rev=109673&view=rev Log: The unix "source" command maps to "command source" in lldb. :-) Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/tools/driver/Driver.cpp Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=109673&r1=109672&r2=109673&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Wed Jul 28 16:16:11 2010 @@ -1153,7 +1153,7 @@ char path[PATH_MAX]; init_file.GetPath(path, sizeof(path)); StreamString source_command; - source_command.Printf ("source '%s'", path); + source_command.Printf ("command source '%s'", path); HandleCommand (source_command.GetData(), false, result); } else Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=109673&r1=109672&r2=109673&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Wed Jul 28 16:16:11 2010 @@ -1137,7 +1137,7 @@ for (size_t i=0; i < num_source_command_files; ++i) { const char *command_file = GetSourceCommandFileAtIndex(i); - ::snprintf (command_string, sizeof(command_string), "source '%s'", command_file); + ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file); m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false); if (GetDebugMode()) { From johnny.chen at apple.com Wed Jul 28 16:24:31 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 28 Jul 2010 21:24:31 -0000 Subject: [Lldb-commits] [lldb] r109674 - /lldb/trunk/test/stl/TestSTL.py Message-ID: <20100728212431.BD5372A6C12C@llvm.org> Author: johnny Date: Wed Jul 28 16:24:31 2010 New Revision: 109674 URL: http://llvm.org/viewvc/llvm-project?rev=109674&view=rev Log: Added a test case to test that we can successfully step into an STL function. This test case currently always fails. Added: lldb/trunk/test/stl/TestSTL.py Added: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=109674&view=auto ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (added) +++ lldb/trunk/test/stl/TestSTL.py Wed Jul 28 16:24:31 2010 @@ -0,0 +1,75 @@ +""" +Test that we can successfully step into an STL function. +""" + +import os, time +import unittest +import lldb +import lldbtest +import time + +class TestSTL(lldbtest.TestBase): + + mydir = "stl" + + def test_step_into_stl(self): + """Test that we can successfully step into an STL function.""" + res = self.res + exe = os.path.join(os.getcwd(), "a.out") + # The following two lines, if uncommented, will enable loggings. + #self.ci.HandleCommand("log enable -f /tmp/lldb.log lldb default", res) + #self.assertTrue(res.Succeeded()) + self.ci.HandleCommand("file " + exe, res) + self.assertTrue(res.Succeeded()) + + # Break on line 13 of main.cpp. + self.ci.HandleCommand("breakpoint set -f main.cpp -l 13", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().startswith( + "Breakpoint created: 1: file ='main.cpp', line = 13, locations = 1") + ) + + self.ci.HandleCommand("run", res) + time.sleep(0.1) + self.assertTrue(res.Succeeded()) + + # Stop at 'std::string hello_world ("Hello World!");'. + self.ci.HandleCommand("thread list", res) + print "thread list ->", res.GetOutput() + self.assertTrue(res.Succeeded()) + output = res.GetOutput() + self.assertTrue(output.find('main.cpp:13') > 0 and + output.find('stop reason = breakpoint') > 0) + + # The breakpoint should have a hit count of 1. + self.ci.HandleCommand("breakpoint list", res) + self.assertTrue(res.Succeeded()) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + + # Now do 'thread step-in', we should stop on the basic_string template. + self.ci.HandleCommand("thread step-in", res) + print "thread step-in:", res.GetOutput() + + # + # This assertion currently always fails. + # + self.assertTrue(res.Succeeded()) + + #self.ci.HandleCommand("process status", res) + #print "process status:", res.GetOutput() + self.ci.HandleCommand("thread backtrace", res) + print "thread backtrace:", res.GetOutput() + self.assertTrue(res.Succeeded()) + output = res.GetOutput() + self.assertTrue(output.find('[inlined]') > 0 and + output.find('basic_string.h') and + output.find('stop reason = step in,') > 0) + + self.ci.HandleCommand("continue", res) + self.assertTrue(res.Succeeded()) + + +if __name__ == '__main__': + lldb.SBDebugger.Initialize() + unittest.main() + lldb.SBDebugger.Terminate() From krister.walfridsson at gmail.com Wed Jul 28 16:58:17 2010 From: krister.walfridsson at gmail.com (Krister Walfridsson) Date: Wed, 28 Jul 2010 23:58:17 +0200 (CEST) Subject: [Lldb-commits] PATCH: update includes needed for NetBSD Message-ID: The attached add some missing includes/updates some includes, needed to compile on NetBSD. /Krister -------------- next part -------------- Index: source/Core/Error.cpp =================================================================== --- source/Core/Error.cpp (revision 109645) +++ source/Core/Error.cpp (working copy) @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // C Includes -#include +#include // C++ Includes // Other libraries and framework includes Index: include/lldb/Core/Error.h =================================================================== --- include/lldb/Core/Error.h (revision 109645) +++ include/lldb/Core/Error.h (working copy) @@ -14,6 +14,7 @@ #ifdef __APPLE__ #include #endif +#include #include #include #include Index: include/lldb/Core/Log.h =================================================================== --- include/lldb/Core/Log.h (revision 109645) +++ include/lldb/Core/Log.h (working copy) @@ -14,6 +14,7 @@ #include #include #include +#include #include #include Index: tools/driver/IOChannel.h =================================================================== --- tools/driver/IOChannel.h (revision 109645) +++ tools/driver/IOChannel.h (working copy) @@ -13,7 +13,11 @@ #include #include +#if defined(__NetBSD__) +#include +#else #include +#endif #include #include "Driver.h" From krister.walfridsson at gmail.com Wed Jul 28 16:59:05 2010 From: krister.walfridsson at gmail.com (Krister Walfridsson) Date: Wed, 28 Jul 2010 23:59:05 +0200 (CEST) Subject: [Lldb-commits] PATCH: NetBSD support in include/lldb/lldb-enumerations.h Message-ID: The attached patch adds support for the NetBSD byte order macros in include/lldb/lldb-enumerations.h. /Krister -------------- next part -------------- Index: include/lldb/lldb-enumerations.h =================================================================== --- include/lldb/lldb-enumerations.h (revision 109645) +++ include/lldb/lldb-enumerations.h (working copy) @@ -10,8 +10,12 @@ #ifndef LLDB_enumerations_h_ #define LLDB_enumerations_h_ -#if !defined (__APPLE__) +#if defined (__NetBSD__) +#include + +#elif !defined (__APPLE__) + #include #endif @@ -94,8 +98,22 @@ #error unable to detect endianness #endif +#elif defined (__NetBSD__) + +// On NetBSD we rely upon the defines in + +#if _BYTE_ORDER == _LITTLE_ENDIAN + eByteOrderHost = eByteOrderLittle +#elif _BYTE_ORDER == _BIG_ENDIAN + eByteOrderHost = eByteOrderBig +#elif _BYTE_ORDER == _PDP_ENDIAN + eByteOrderHost = eByteOrderPDP #else +#error unable to detect endianness +#endif +#else + // On linux we rely upon the defines in #if __BYTE_ORDER == __LITTLE_ENDIAN From krister.walfridsson at gmail.com Wed Jul 28 17:00:21 2010 From: krister.walfridsson at gmail.com (Krister Walfridsson) Date: Thu, 29 Jul 2010 00:00:21 +0200 (CEST) Subject: [Lldb-commits] PATCH: Make scripts/generate-vers.pl work on NetBSD Message-ID: NetBSD does not have perl in /usr/bin, so the attached patch use $(PERL) to run the scripts/generate-vers.pl script. /Krister -------------- next part -------------- Index: source/Makefile =================================================================== --- source/Makefile (revision 109645) +++ source/Makefile (working copy) @@ -17,4 +17,4 @@ include $(LLDB_LEVEL)/Makefile LLDB_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj - "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj" > LLDB_vers.c + "$(PERL)" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj" > LLDB_vers.c From johnny.chen at apple.com Wed Jul 28 17:00:42 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 28 Jul 2010 22:00:42 -0000 Subject: [Lldb-commits] [lldb] r109678 - /lldb/trunk/test/stl/TestSTL.py Message-ID: <20100728220042.E536C2A6C12C@llvm.org> Author: johnny Date: Wed Jul 28 17:00:42 2010 New Revision: 109678 URL: http://llvm.org/viewvc/llvm-project?rev=109678&view=rev Log: Add some comment about possible related bug info. Modified: lldb/trunk/test/stl/TestSTL.py Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=109678&r1=109677&r2=109678&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Wed Jul 28 17:00:42 2010 @@ -22,6 +22,9 @@ self.ci.HandleCommand("file " + exe, res) self.assertTrue(res.Succeeded()) + self.ci.HandleCommand("run", res) + time.sleep(1) + # Break on line 13 of main.cpp. self.ci.HandleCommand("breakpoint set -f main.cpp -l 13", res) self.assertTrue(res.Succeeded()) @@ -30,7 +33,7 @@ ) self.ci.HandleCommand("run", res) - time.sleep(0.1) + time.sleep(1) self.assertTrue(res.Succeeded()) # Stop at 'std::string hello_world ("Hello World!");'. @@ -52,6 +55,7 @@ # # This assertion currently always fails. + # This might be related: rdar://problem/8247112. # self.assertTrue(res.Succeeded()) From johnny.chen at apple.com Wed Jul 28 19:40:06 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 29 Jul 2010 00:40:06 -0000 Subject: [Lldb-commits] [lldb] r109712 - /lldb/trunk/test/stl/TestSTL.py Message-ID: <20100729004006.736162A6C12C@llvm.org> Author: johnny Date: Wed Jul 28 19:40:06 2010 New Revision: 109712 URL: http://llvm.org/viewvc/llvm-project?rev=109712&view=rev Log: Removed debug stmts checked into the previous commit. Modified: lldb/trunk/test/stl/TestSTL.py Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=109712&r1=109711&r2=109712&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Wed Jul 28 19:40:06 2010 @@ -22,9 +22,6 @@ self.ci.HandleCommand("file " + exe, res) self.assertTrue(res.Succeeded()) - self.ci.HandleCommand("run", res) - time.sleep(1) - # Break on line 13 of main.cpp. self.ci.HandleCommand("breakpoint set -f main.cpp -l 13", res) self.assertTrue(res.Succeeded()) @@ -33,7 +30,7 @@ ) self.ci.HandleCommand("run", res) - time.sleep(1) + time.sleep(0.1) self.assertTrue(res.Succeeded()) # Stop at 'std::string hello_world ("Hello World!");'. From scallanan at apple.com Thu Jul 29 14:03:08 2010 From: scallanan at apple.com (Sean Callanan) Date: Thu, 29 Jul 2010 19:03:08 -0000 Subject: [Lldb-commits] [lldb] r109792 - /lldb/trunk/source/Expression/ClangExpression.cpp Message-ID: <20100729190308.D130E2A6C12C@llvm.org> Author: spyffe Date: Thu Jul 29 14:03:08 2010 New Revision: 109792 URL: http://llvm.org/viewvc/llvm-project?rev=109792&view=rev Log: Fixed the expression code to use the right code model with the JIT. Modified: lldb/trunk/source/Expression/ClangExpression.cpp Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=109792&r1=109791&r2=109792&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Thu Jul 29 14:03:08 2010 @@ -194,6 +194,8 @@ m_target_triple = target_triple; else m_target_triple = llvm::sys::getHostTriple(); + + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); } @@ -539,17 +541,6 @@ m_jit_mm_ptr = new RecordingMemoryManager(); //llvm::InitializeNativeTarget(); - - if (m_execution_engine.get() == 0) - m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, - &error, - m_jit_mm_ptr, - CodeGenOpt::Default, - true, - CodeModel::Default)); - - m_execution_engine->DisableLazyCompilation(); - llvm::Function *function = module->getFunction (llvm::StringRef (name)); if (log) { @@ -557,22 +548,33 @@ switch (llvm::TargetMachine::getRelocationModel()) { - case llvm::Reloc::Default: - relocation_model_string = "Default"; - break; - case llvm::Reloc::Static: - relocation_model_string = "Static"; - break; - case llvm::Reloc::PIC_: - relocation_model_string = "PIC_++"; - break; - case llvm::Reloc::DynamicNoPIC: - relocation_model_string = "DynamicNoPIC"; - break; + case llvm::Reloc::Default: + relocation_model_string = "Default"; + break; + case llvm::Reloc::Static: + relocation_model_string = "Static"; + break; + case llvm::Reloc::PIC_: + relocation_model_string = "PIC_"; + break; + case llvm::Reloc::DynamicNoPIC: + relocation_model_string = "DynamicNoPIC"; + break; } log->Printf("Target machine's relocation model: %s", relocation_model_string); } + + if (m_execution_engine.get() == 0) + m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, + &error, + m_jit_mm_ptr, + CodeGenOpt::Default, + true, + CodeModel::Small)); // set to small so RIP-relative relocations work in PIC + + m_execution_engine->DisableLazyCompilation(); + llvm::Function *function = module->getFunction (llvm::StringRef (name)); // We don't actually need the function pointer here, this just forces it to get resolved. void *fun_ptr = m_execution_engine->getPointerToFunction(function); From gclayton at apple.com Thu Jul 29 14:36:30 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 29 Jul 2010 19:36:30 -0000 Subject: [Lldb-commits] [lldb] r109793 - /lldb/trunk/source/Commands/CommandObjectExpression.cpp Message-ID: <20100729193630.2AF8F2A6C12C@llvm.org> Author: gclayton Date: Thu Jul 29 14:36:30 2010 New Revision: 109793 URL: http://llvm.org/viewvc/llvm-project?rev=109793&view=rev Log: Fixed expression result printing to have the expression result type be in parens and to have a space before the value. Before: (lldb) expr 3 + 1 int4 (lldb) expr 3 + 1 (int) 4 Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=109793&r1=109792&r2=109793&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Jul 29 14:36:30 2010 @@ -464,7 +464,7 @@ if (clang_type) { if (m_options.show_types) - output_stream.PutCString(ClangASTType::GetClangTypeName (clang_type).GetCString()); + output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to clang_type, // The opaque clang type we want to dump that value of From johnny.chen at apple.com Thu Jul 29 14:51:52 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 29 Jul 2010 19:51:52 -0000 Subject: [Lldb-commits] [lldb] r109794 - /lldb/trunk/source/Expression/ClangExpression.cpp Message-ID: <20100729195152.556B62A6C12C@llvm.org> Author: johnny Date: Thu Jul 29 14:51:52 2010 New Revision: 109794 URL: http://llvm.org/viewvc/llvm-project?rev=109794&view=rev Log: Fixed "warning: unused variable 'log'". Modified: lldb/trunk/source/Expression/ClangExpression.cpp Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=109794&r1=109793&r2=109794&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Thu Jul 29 14:51:52 2010 @@ -194,8 +194,6 @@ m_target_triple = target_triple; else m_target_triple = llvm::sys::getHostTriple(); - - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); } From gclayton at apple.com Thu Jul 29 15:06:32 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 29 Jul 2010 20:06:32 -0000 Subject: [Lldb-commits] [lldb] r109795 - /lldb/trunk/source/Symbol/ClangASTContext.cpp Message-ID: <20100729200632.A557B2A6C12C@llvm.org> Author: gclayton Date: Thu Jul 29 15:06:32 2010 New Revision: 109795 URL: http://llvm.org/viewvc/llvm-project?rev=109795&view=rev Log: Fixed "void *ClangASTContext::CreatePointerType (void *clang_type);" to return objective C pointers for clang::Type::TypeClass types that are "clang::Type::ObjCObject" and "clang::Type::ObjCInterface" . Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=109795&r1=109794&r2=109795&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Jul 29 15:06:32 2010 @@ -2594,7 +2594,25 @@ ClangASTContext::CreatePointerType (void *clang_type) { if (clang_type) - return getASTContext()->getPointerType(QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); + { + QualType qual_type (QualType::getFromOpaquePtr(clang_type)); + + switch (qual_type->getTypeClass()) + { + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + // TODO: find out if I need to make a pointer or objc pointer for "clang::Type::ObjCObjectPointer" types + //case clang::Type::ObjCObjectPointer: + return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); + + // TODO: can we detect if this type is a block type? +// case clang::Type::BlockType: +// return getASTContext()->getBlockPointerType(qual_type).getAsOpaquePtr(); + + default: + return getASTContext()->getPointerType(qual_type).getAsOpaquePtr(); + } + } return NULL; } From gclayton at apple.com Thu Jul 29 15:08:39 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 29 Jul 2010 20:08:39 -0000 Subject: [Lldb-commits] [lldb] r109798 - in /lldb/trunk/test/foundation: ./ Makefile main.m Message-ID: <20100729200840.071DF2A6C12C@llvm.org> Author: gclayton Date: Thu Jul 29 15:08:39 2010 New Revision: 109798 URL: http://llvm.org/viewvc/llvm-project?rev=109798&view=rev Log: Added an objective C test case. Added: lldb/trunk/test/foundation/ lldb/trunk/test/foundation/Makefile lldb/trunk/test/foundation/main.m Added: lldb/trunk/test/foundation/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/Makefile?rev=109798&view=auto ============================================================================== --- lldb/trunk/test/foundation/Makefile (added) +++ lldb/trunk/test/foundation/Makefile Thu Jul 29 15:08:39 2010 @@ -0,0 +1,125 @@ +#---------------------------------------------------------------------- +# Fill in the source files to build +#---------------------------------------------------------------------- +C_SOURCES := +CXX_SOURCES := +OBJC_SOURCES :=main.m +OBJCXX_SOURCES := + +# Uncomment line below for debugging shell commands +# SHELL = /bin/sh -x + +#---------------------------------------------------------------------- +# Change any build/tool options needed +#---------------------------------------------------------------------- +DS := /usr/bin/dsymutil +DSFLAGS = +CFLAGS ?=-arch x86_64 -g -O0 +CPLUSPLUSFLAGS +=$(CFLAGS) +CPPFLAGS +=$(CFLAGS) +LD = gcc +LDFLAGS = $(CFLAGS) -lobjc -framework Foundation +OBJECTS = +EXE=a.out +DSYM=$(EXE).dSYM + +#---------------------------------------------------------------------- +# Check if we have any C source files +#---------------------------------------------------------------------- +ifneq "$(strip $(C_SOURCES))" "" + OBJECTS +=$(strip $(C_SOURCES:.c=.o)) +endif + +#---------------------------------------------------------------------- +# Check if we have any C++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(CXX_SOURCES))" "" + OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) + LD = g++ +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJC_SOURCES))" "" + OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) + LDFLAGS +=-lobjc +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJCXX_SOURCES))" "" + OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) + LD = g++ + ifeq $(findstring lobjc,$(LDFLAGS)) "" + LDFLAGS +=-lobjc + endif +endif + + +#---------------------------------------------------------------------- +# Make the dSYM file from the executable +#---------------------------------------------------------------------- +$(DSYM) : $(EXE) + $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" + +#---------------------------------------------------------------------- +# Compile the executable from all the objects (default rule) with no +# dsym file. +#---------------------------------------------------------------------- +$(EXE) : $(OBJECTS) + $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" + + +#---------------------------------------------------------------------- +# Automatic variables based on items already entered. Below we create +# an objects lists from the list of sources by replacing all entries +# that end with .c with .o, and we also create a list of prerequisite +# files by replacing all .c files with .d. +#---------------------------------------------------------------------- +PREREQS := $(OBJECTS:.o=.d) + +#---------------------------------------------------------------------- +# Rule for Generating Prerequisites Automatically using .d files and +# the compiler -MM option. The -M option will list all system headers, +# and the -MM option will list all non-system dependencies. +#---------------------------------------------------------------------- +%.d: %.c + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.cpp + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.m + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.mm + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +#---------------------------------------------------------------------- +# Include all of the makefiles for each source file so we don't have +# to manually track all of the prerequisites for each source file. +#---------------------------------------------------------------------- +sinclude $(PREREQS) + +.PHONY: clean +dsym: $(DSYM) +all: $(EXE) $(DSYM) +clean: + rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) + + + Added: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=109798&view=auto ============================================================================== --- lldb/trunk/test/foundation/main.m (added) +++ lldb/trunk/test/foundation/main.m Thu Jul 29 15:08:39 2010 @@ -0,0 +1,9 @@ +#import + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", argv[0]]; + [pool release]; + return 0; +} From eli.friedman at gmail.com Thu Jul 29 15:34:05 2010 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 29 Jul 2010 13:34:05 -0700 Subject: [Lldb-commits] [lldb] r109795 - /lldb/trunk/source/Symbol/ClangASTContext.cpp In-Reply-To: <20100729200632.A557B2A6C12C@llvm.org> References: <20100729200632.A557B2A6C12C@llvm.org> Message-ID: On Thu, Jul 29, 2010 at 1:06 PM, Greg Clayton wrote: > + ? ? ? ?case clang::Type::ObjCObject: > + ? ? ? ?case clang::Type::ObjCInterface: > + ? ? ? ?// TODO: find out if I need to make a pointer or objc pointer for "clang::Type::ObjCObjectPointer" types > + ? ? ? ?//case clang::Type::ObjCObjectPointer: > + ? ? ? ? ? ?return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); AFAIK, a pointer to an ObjC pointer is just a regular pointer. > + ? ? ? ?// TODO: can we detect if this type is a block type? > +// ? ? ?case clang::Type::BlockType: > +// ? ? ? ? ?return getASTContext()->getBlockPointerType(qual_type).getAsOpaquePtr(); There is no such thing as a block type; block pointers can't be dereferenced, only called. -Eli From gclayton at apple.com Thu Jul 29 15:38:50 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 29 Jul 2010 20:38:50 -0000 Subject: [Lldb-commits] [lldb] r109802 - /lldb/trunk/source/Symbol/ClangASTContext.cpp Message-ID: <20100729203850.791302A6C12C@llvm.org> Author: gclayton Date: Thu Jul 29 15:38:50 2010 New Revision: 109802 URL: http://llvm.org/viewvc/llvm-project?rev=109802&view=rev Log: Removed pending TODOs after resolving them with help of the clang folks and the discussion list. Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=109802&r1=109801&r2=109802&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Jul 29 15:38:50 2010 @@ -2601,14 +2601,8 @@ { case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - // TODO: find out if I need to make a pointer or objc pointer for "clang::Type::ObjCObjectPointer" types - //case clang::Type::ObjCObjectPointer: return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); - // TODO: can we detect if this type is a block type? -// case clang::Type::BlockType: -// return getASTContext()->getBlockPointerType(qual_type).getAsOpaquePtr(); - default: return getASTContext()->getPointerType(qual_type).getAsOpaquePtr(); } From johnny.chen at apple.com Thu Jul 29 15:49:07 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 29 Jul 2010 20:49:07 -0000 Subject: [Lldb-commits] [lldb] r109803 - /lldb/trunk/test/stl/TestSTL.py Message-ID: <20100729204907.BA0172A6C12C@llvm.org> Author: johnny Date: Thu Jul 29 15:49:07 2010 New Revision: 109803 URL: http://llvm.org/viewvc/llvm-project?rev=109803&view=rev Log: Removed redundant import statement. Modified: lldb/trunk/test/stl/TestSTL.py Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=109803&r1=109802&r2=109803&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Thu Jul 29 15:49:07 2010 @@ -6,7 +6,6 @@ import unittest import lldb import lldbtest -import time class TestSTL(lldbtest.TestBase): From johnny.chen at apple.com Thu Jul 29 16:42:28 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 29 Jul 2010 21:42:28 -0000 Subject: [Lldb-commits] [lldb] r109806 - in /lldb/trunk/test/command_source: ./ .lldb TestCommandSource.py my.py Message-ID: <20100729214228.3CC6E2A6C12C@llvm.org> Author: johnny Date: Thu Jul 29 16:42:28 2010 New Revision: 109806 URL: http://llvm.org/viewvc/llvm-project?rev=109806&view=rev Log: Add a test case to test that lldb command "command source" works correctly. Added: lldb/trunk/test/command_source/ lldb/trunk/test/command_source/.lldb lldb/trunk/test/command_source/TestCommandSource.py lldb/trunk/test/command_source/my.py Added: lldb/trunk/test/command_source/.lldb URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/.lldb?rev=109806&view=auto ============================================================================== --- lldb/trunk/test/command_source/.lldb (added) +++ lldb/trunk/test/command_source/.lldb Thu Jul 29 16:42:28 2010 @@ -0,0 +1 @@ +script import my Added: lldb/trunk/test/command_source/TestCommandSource.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/TestCommandSource.py?rev=109806&view=auto ============================================================================== --- lldb/trunk/test/command_source/TestCommandSource.py (added) +++ lldb/trunk/test/command_source/TestCommandSource.py Thu Jul 29 16:42:28 2010 @@ -0,0 +1,31 @@ +""" +Test that lldb command "command source" works correctly. +""" + +import os, time +import unittest +import lldb +import lldbtest + +class TestCommandSource(lldbtest.TestBase): + + mydir = "command_source" + + def test_command_source(self): + """Test that lldb command "command source" works correctly.""" + res = self.res + + # Sourcing .lldb in the current working directory, which in turn imports + # the "my" package that defines the date() function. + self.ci.HandleCommand("command source .lldb", res) + self.assertTrue(res.Succeeded()) + + self.ci.HandleCommand("script my.date()", res) + self.assertTrue(res.Succeeded()) + + time.sleep(1) + +if __name__ == '__main__': + lldb.SBDebugger.Initialize() + unittest.main() + lldb.SBDebugger.Terminate() Added: lldb/trunk/test/command_source/my.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/my.py?rev=109806&view=auto ============================================================================== --- lldb/trunk/test/command_source/my.py (added) +++ lldb/trunk/test/command_source/my.py Thu Jul 29 16:42:28 2010 @@ -0,0 +1,4 @@ +def date(): + import datetime + today = datetime.date.today() + print today From gclayton at apple.com Fri Jul 30 15:12:55 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 30 Jul 2010 20:12:55 -0000 Subject: [Lldb-commits] [lldb] r109882 - in /lldb/trunk: include/lldb/API/SBDebugger.h include/lldb/API/SBTarget.h include/lldb/API/SBThread.h source/API/SBDebugger.cpp source/API/SBTarget.cpp source/API/SBThread.cpp Message-ID: <20100730201255.5AF502A6C12C@llvm.org> Author: gclayton Date: Fri Jul 30 15:12:55 2010 New Revision: 109882 URL: http://llvm.org/viewvc/llvm-project?rev=109882&view=rev Log: Added "void Clear();" methods to SBDebugger, SBTarget and SBThread so they can release their shared pointers. Modified: lldb/trunk/include/lldb/API/SBDebugger.h lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/include/lldb/API/SBThread.h lldb/trunk/source/API/SBDebugger.cpp lldb/trunk/source/API/SBTarget.cpp lldb/trunk/source/API/SBThread.cpp Modified: lldb/trunk/include/lldb/API/SBDebugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=109882&r1=109881&r2=109882&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDebugger.h (original) +++ lldb/trunk/include/lldb/API/SBDebugger.h Fri Jul 30 15:12:55 2010 @@ -34,6 +34,9 @@ IsValid() const; void + Clear (); + + void SetAsync (bool b); void Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=109882&r1=109881&r2=109882&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Fri Jul 30 15:12:55 2010 @@ -76,6 +76,9 @@ lldb::SBModule FindModule (const lldb::SBFileSpec &file_spec); + void + Clear (); + bool DeleteTargetFromList (lldb_private::TargetList *list); Modified: lldb/trunk/include/lldb/API/SBThread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=109882&r1=109881&r2=109882&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBThread.h (original) +++ lldb/trunk/include/lldb/API/SBThread.h Fri Jul 30 15:12:55 2010 @@ -30,6 +30,9 @@ bool IsValid() const; + void + Clear (); + lldb::StopReason GetStopReason(); Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=109882&r1=109881&r2=109882&view=diff ============================================================================== --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Fri Jul 30 15:12:55 2010 @@ -43,6 +43,12 @@ Debugger::Terminate(); } +void +SBDebugger::Clear () +{ + m_opaque_sp.reset(); +} + SBDebugger SBDebugger::Create() { Modified: lldb/trunk/source/API/SBTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=109882&r1=109881&r2=109882&view=diff ============================================================================== --- lldb/trunk/source/API/SBTarget.cpp (original) +++ lldb/trunk/source/API/SBTarget.cpp Fri Jul 30 15:12:55 2010 @@ -353,6 +353,13 @@ return 0; } +void +SBTarget::Clear () +{ + m_opaque_sp.reset(); +} + + SBModule SBTarget::FindModule (const SBFileSpec &sb_file_spec) { Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=109882&r1=109881&r2=109882&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Fri Jul 30 15:12:55 2010 @@ -67,6 +67,13 @@ return m_opaque_sp != NULL; } +void +SBThread::Clear () +{ + m_opaque_sp.reset(); +} + + StopReason SBThread::GetStopReason() { From gclayton at apple.com Fri Jul 30 15:30:45 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 30 Jul 2010 20:30:45 -0000 Subject: [Lldb-commits] [lldb] r109887 - in /lldb/trunk: llvm.zip scripts/build-llvm.pl source/Expression/ClangExpression.cpp source/Expression/IRForTarget.cpp source/Symbol/ClangASTContext.cpp Message-ID: <20100730203045.256C52A6C12C@llvm.org> Author: gclayton Date: Fri Jul 30 15:30:44 2010 New Revision: 109887 URL: http://llvm.org/viewvc/llvm-project?rev=109887&view=rev Log: Updated to llvm/clang from July 30, 2010 at 08:00. Modified: lldb/trunk/llvm.zip lldb/trunk/scripts/build-llvm.pl lldb/trunk/source/Expression/ClangExpression.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/llvm.zip URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/llvm.zip?rev=109887&r1=109886&r2=109887&view=diff ============================================================================== Binary files - no diff available. Modified: lldb/trunk/scripts/build-llvm.pl URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/build-llvm.pl?rev=109887&r1=109886&r2=109887&view=diff ============================================================================== --- lldb/trunk/scripts/build-llvm.pl (original) +++ lldb/trunk/scripts/build-llvm.pl Fri Jul 30 15:30:44 2010 @@ -25,7 +25,7 @@ our $llvm_configuration = $ENV{LLVM_CONFIGURATION}; -our $llvm_revision = "'{2010-07-20T16:00}'"; +our $llvm_revision = "'{2010-07-30T08:00}'"; our $llvm_source_dir = "$ENV{SRCROOT}"; our $cc = "$ENV{DEVELOPER_BIN_DIR}/gcc-4.2"; our $cxx = "$ENV{DEVELOPER_BIN_DIR}/g++-4.2"; Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=109887&r1=109886&r2=109887&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Fri Jul 30 15:30:44 2010 @@ -107,74 +107,88 @@ // Main driver //===----------------------------------------------------------------------===// -void LLVMErrorHandler(void *UserData, const std::string &Message) { - Diagnostic &Diags = *static_cast(UserData); +//===----------------------------------------------------------------------===// +// Main driver +//===----------------------------------------------------------------------===// - Diags.Report(diag::err_fe_error_backend) << Message; +static void LLVMErrorHandler(void *UserData, const std::string &Message) { + Diagnostic &Diags = *static_cast(UserData); - // We cannot recover from llvm errors. - exit(1); + Diags.Report(diag::err_fe_error_backend) << Message; + + // We cannot recover from llvm errors. + exit(1); } static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { - using namespace clang::frontend; + using namespace clang::frontend; - switch (CI.getFrontendOpts().ProgramAction) { - default: - llvm_unreachable("Invalid program action!"); - - case ASTDump: return new ASTDumpAction(); - case ASTPrint: return new ASTPrintAction(); - case ASTPrintXML: return new ASTPrintXMLAction(); - case ASTView: return new ASTViewAction(); - case DumpRawTokens: return new DumpRawTokensAction(); - case DumpTokens: return new DumpTokensAction(); - case EmitAssembly: return new EmitAssemblyAction(); - case EmitBC: return new EmitBCAction(); - case EmitHTML: return new HTMLPrintAction(); - case EmitLLVM: return new EmitLLVMAction(); - case EmitLLVMOnly: return new EmitLLVMOnlyAction(); - case EmitObj: return new EmitObjAction(); - case FixIt: return new FixItAction(); - case GeneratePCH: return new GeneratePCHAction(); - case GeneratePTH: return new GeneratePTHAction(); - case InheritanceView: return new InheritanceViewAction(); - case InitOnly: return new InitOnlyAction(); - case ParseNoop: return new ParseOnlyAction(); - case ParsePrintCallbacks: return new PrintParseAction(); - case ParseSyntaxOnly: return new SyntaxOnlyAction(); - - case PluginAction: { - if (CI.getFrontendOpts().ActionName == "help") { - llvm::errs() << "clang -cc1 plugins:\n"; - for (FrontendPluginRegistry::iterator it = - FrontendPluginRegistry::begin(), - ie = FrontendPluginRegistry::end(); - it != ie; ++it) - llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n"; - return 0; - } + switch (CI.getFrontendOpts().ProgramAction) { + default: + llvm_unreachable("Invalid program action!"); + + case ASTDump: return new ASTDumpAction(); + case ASTPrint: return new ASTPrintAction(); + case ASTPrintXML: return new ASTPrintXMLAction(); + case ASTView: return new ASTViewAction(); + case BoostCon: return new BoostConAction(); + case DumpRawTokens: return new DumpRawTokensAction(); + case DumpTokens: return new DumpTokensAction(); + case EmitAssembly: return new EmitAssemblyAction(); + case EmitBC: return new EmitBCAction(); + case EmitHTML: return new HTMLPrintAction(); + case EmitLLVM: return new EmitLLVMAction(); + case EmitLLVMOnly: return new EmitLLVMOnlyAction(); + case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); + case EmitObj: return new EmitObjAction(); + case FixIt: return new FixItAction(); + case GeneratePCH: return new GeneratePCHAction(); + case GeneratePTH: return new GeneratePTHAction(); + case InheritanceView: return new InheritanceViewAction(); + case InitOnly: return new InitOnlyAction(); + case ParseSyntaxOnly: return new SyntaxOnlyAction(); + + case PluginAction: { + + for (FrontendPluginRegistry::iterator it = + FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); + it != ie; ++it) { + if (it->getName() == CI.getFrontendOpts().ActionName) { + PluginASTAction* plugin = it->instantiate(); + plugin->ParseArgs(CI.getFrontendOpts().PluginArgs); + return plugin; + } + } - for (FrontendPluginRegistry::iterator it = - FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - if (it->getName() == CI.getFrontendOpts().ActionName) - return it->instantiate(); - } + CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) + << CI.getFrontendOpts().ActionName; + return 0; + } - CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) - << CI.getFrontendOpts().ActionName; - return 0; - } + case PrintDeclContext: return new DeclContextPrintAction(); + case PrintPreamble: return new PrintPreambleAction(); + case PrintPreprocessedInput: return new PrintPreprocessedAction(); + case RewriteMacros: return new RewriteMacrosAction(); + case RewriteObjC: return new RewriteObjCAction(); + case RewriteTest: return new RewriteTestAction(); + case RunAnalysis: return new AnalysisAction(); + case RunPreprocessorOnly: return new PreprocessOnlyAction(); + } +} + +static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { + // Create the underlying action. + FrontendAction *Act = CreateFrontendBaseAction(CI); + if (!Act) + return 0; - case PrintDeclContext: return new DeclContextPrintAction(); - case PrintPreprocessedInput: return new PrintPreprocessedAction(); - case RewriteMacros: return new RewriteMacrosAction(); - case RewriteObjC: return new RewriteObjCAction(); - case RewriteTest: return new RewriteTestAction(); - case RunAnalysis: return new AnalysisAction(); - case RunPreprocessorOnly: return new PreprocessOnlyAction(); - } + // If there are any AST files to merge, create a frontend action + // adaptor to perform the merge. + if (!CI.getFrontendOpts().ASTMergeFiles.empty()) + Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0], + CI.getFrontendOpts().ASTMergeFiles.size()); + + return Act; } //---------------------------------------------------------------------- @@ -330,7 +344,8 @@ m_clang_ap->getTarget(), m_clang_ap->getPreprocessor().getIdentifierTable(), selector_table, - *builtin_ap.get()); + *builtin_ap.get(), + 0); llvm::OwningPtr ASTSource(new ClangASTSource(*Context, *m_decl_map)); @@ -426,24 +441,6 @@ return num_errors; } -static FrontendAction * -CreateFrontendAction(CompilerInstance &CI) -{ - // Create the underlying action. - FrontendAction *Act = CreateFrontendBaseAction(CI); - if (!Act) - return 0; - - // If there are any AST files to merge, create a frontend action - // adaptor to perform the merge. - if (!CI.getFrontendOpts().ASTMergeFiles.empty()) - Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0], - CI.getFrontendOpts().ASTMergeFiles.size()); - - return Act; -} - - unsigned ClangExpression::ConvertExpressionToDWARF (ClangExpressionVariableList& expr_local_variable_list, StreamString &dwarf_opcode_strm) Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=109887&r1=109886&r2=109887&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Fri Jul 30 15:30:44 2010 @@ -242,7 +242,7 @@ ui != guard_load->use_end(); ++ui) { - if (isa(ui)) + if (isa(*ui)) { // do nothing for the moment } Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=109887&r1=109886&r2=109887&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Jul 30 15:30:44 2010 @@ -306,7 +306,8 @@ *getTargetInfo(), *getIdentifierTable(), *getSelectorTable(), - *getBuiltinContext())); + *getBuiltinContext(), + 0)); } return m_ast_context_ap.get(); } @@ -954,7 +955,11 @@ ClangASTContext::CreateBaseClassSpecifier (void *base_class_type, AccessType access, bool is_virtual, bool base_of_class) { if (base_class_type) - return new CXXBaseSpecifier(SourceRange(), is_virtual, base_of_class, (AccessSpecifier)access, QualType::getFromOpaquePtr(base_class_type)); + return new CXXBaseSpecifier (SourceRange(), + is_virtual, + base_of_class, + ConvertAccessTypeToAccessSpecifier (access), + getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type))); return NULL; } From johnny.chen at apple.com Fri Jul 30 17:33:14 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 30 Jul 2010 22:33:14 -0000 Subject: [Lldb-commits] [lldb] r109899 - in /lldb/trunk: include/lldb/Interpreter/ScriptInterpreter.h include/lldb/Interpreter/ScriptInterpreterNone.h include/lldb/Interpreter/ScriptInterpreterPython.h source/Interpreter/CommandObjectScript.cpp source/Interpreter/ScriptInterpreterNone.cpp source/Interpreter/ScriptInterpreterPython.cpp test/command_source/TestCommandSource.py Message-ID: <20100730223314.4CABA2A6C12C@llvm.org> Author: johnny Date: Fri Jul 30 17:33:14 2010 New Revision: 109899 URL: http://llvm.org/viewvc/llvm-project?rev=109899&view=rev Log: We can do better when reporting the status of one-liner script execution. Change the prototype of ScriptInterpreter::ExecuteOneLine() to return bool instead of void and take one additional parameter as CommandReturnObject *. Propagate the status of one-liner execution back appropriately. Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h lldb/trunk/include/lldb/Interpreter/ScriptInterpreterNone.h lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h lldb/trunk/source/Interpreter/CommandObjectScript.cpp lldb/trunk/source/Interpreter/ScriptInterpreterNone.cpp lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp lldb/trunk/test/command_source/TestCommandSource.py Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Fri Jul 30 17:33:14 2010 @@ -42,8 +42,8 @@ virtual ~ScriptInterpreter (); - virtual void - ExecuteOneLine (CommandInterpreter &interpreter, const char *command) = 0; + virtual bool + ExecuteOneLine (CommandInterpreter &interpreter, const char *command, CommandReturnObject *result) = 0; virtual void ExecuteInterpreterLoop (CommandInterpreter &interpreter) = 0; Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterNone.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterNone.h?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterNone.h (original) +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterNone.h Fri Jul 30 17:33:14 2010 @@ -22,10 +22,10 @@ ~ScriptInterpreterNone (); - virtual void - ExecuteOneLine (CommandInterpreter &interpreter, const char *command); + bool + ExecuteOneLine (CommandInterpreter &interpreter, const char *command, CommandReturnObject *result); - virtual void + void ExecuteInterpreterLoop (CommandInterpreter &interpreter); }; Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original) +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Fri Jul 30 17:33:14 2010 @@ -24,8 +24,8 @@ ~ScriptInterpreterPython (); - void - ExecuteOneLine (CommandInterpreter &interpreter, const char *command); + bool + ExecuteOneLine (CommandInterpreter &interpreter, const char *command, CommandReturnObject *result); void ExecuteInterpreterLoop (CommandInterpreter &interpreter); Modified: lldb/trunk/source/Interpreter/CommandObjectScript.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObjectScript.cpp?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandObjectScript.cpp (original) +++ lldb/trunk/source/Interpreter/CommandObjectScript.cpp Fri Jul 30 17:33:14 2010 @@ -56,11 +56,18 @@ result.SetStatus (eReturnStatusFailed); } - if (command == NULL || command[0] == '\0') + if (command == NULL || command[0] == '\0') { script_interpreter->ExecuteInterpreterLoop (interpreter); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + + // We can do better when reporting the status of one-liner script execution. + if (script_interpreter->ExecuteOneLine (interpreter, command, &result)) + result.SetStatus(eReturnStatusSuccessFinishNoResult); else - script_interpreter->ExecuteOneLine (interpreter, command); - result.SetStatus (eReturnStatusSuccessFinishNoResult); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); } Modified: lldb/trunk/source/Interpreter/ScriptInterpreterNone.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterNone.cpp?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterNone.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterNone.cpp Fri Jul 30 17:33:14 2010 @@ -25,10 +25,11 @@ { } -void -ScriptInterpreterNone::ExecuteOneLine (CommandInterpreter &interpreter, const char *command) +bool +ScriptInterpreterNone::ExecuteOneLine (CommandInterpreter &interpreter, const char *command, CommandReturnObject *) { interpreter.GetDebugger().GetErrorStream().PutCString ("error: there is no embedded script interpreter in this mode.\n"); + return false; } void Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Fri Jul 30 17:33:14 2010 @@ -258,17 +258,28 @@ Py_Finalize (); } -void -ScriptInterpreterPython::ExecuteOneLine (CommandInterpreter &interpreter, const char *command) +bool +ScriptInterpreterPython::ExecuteOneLine (CommandInterpreter &interpreter, + const char *command, + CommandReturnObject *result = 0) { if (command) { int success; success = PyRun_SimpleString (command); - if (success != 0) - interpreter.GetDebugger().GetErrorStream().Printf ("error: python failed attempting to evaluate '%s'\n", command); + if (success == 0) + return true; + + // The one-liner failed. Append the error message. + if (result) + result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command); + return false; } + + if (result) + result->AppendError ("empty command passed to python\n"); + return false; } Modified: lldb/trunk/test/command_source/TestCommandSource.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/TestCommandSource.py?rev=109899&r1=109898&r2=109899&view=diff ============================================================================== --- lldb/trunk/test/command_source/TestCommandSource.py (original) +++ lldb/trunk/test/command_source/TestCommandSource.py Fri Jul 30 17:33:14 2010 @@ -21,6 +21,8 @@ self.assertTrue(res.Succeeded()) self.ci.HandleCommand("script my.date()", res) + if (not res.Succeeded()): + print res.GetError() self.assertTrue(res.Succeeded()) time.sleep(1) From gclayton at apple.com Fri Jul 30 18:14:42 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 30 Jul 2010 23:14:42 -0000 Subject: [Lldb-commits] [lldb] r109930 - in /lldb/trunk/tools/debugserver/source: MacOSX/MachProcess.cpp MacOSX/MachProcess.h MacOSX/MachTask.cpp debugserver.cpp Message-ID: <20100730231442.D7C1F2A6C12D@llvm.org> Author: gclayton Date: Fri Jul 30 18:14:42 2010 New Revision: 109930 URL: http://llvm.org/viewvc/llvm-project?rev=109930&view=rev Log: Fixed debugserver to not exit when we are able to spawn the process, yet not launch it due to not being able to get the task port. A SIGHUP was killing us and also an error string wasn't properly being passed along. Got rid of a class error variable that can only lead to multi-threaded crashes. Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp lldb/trunk/tools/debugserver/source/debugserver.cpp Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=109930&r1=109929&r2=109930&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp Fri Jul 30 18:14:42 2010 @@ -101,7 +101,6 @@ m_threadList (), m_exception_messages (), m_exception_messages_mutex (PTHREAD_MUTEX_RECURSIVE), - m_err (KERN_SUCCESS), m_state (eStateUnloaded), m_state_mutex (PTHREAD_MUTEX_RECURSIVE), m_events (0, kAllEventsMask), @@ -276,8 +275,6 @@ PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex); m_exception_messages.clear(); } - m_err.Clear(); - } @@ -286,8 +283,7 @@ { DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__); // Create the thread that watches for the child STDIO - m_err = ::pthread_create (&m_stdio_thread, NULL, MachProcess::STDIOThread, this); - return m_err.Success(); + return ::pthread_create (&m_stdio_thread, NULL, MachProcess::STDIOThread, this) == 0; } @@ -308,19 +304,15 @@ if (CanResume(state)) { PrivateResume(thread_actions); + return true; } else if (state == eStateRunning) { DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x is running, ignoring...", m_task.TaskPort()); - m_err.Clear(); - - } - else - { - DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x can't continue, ignoring...", m_task.TaskPort()); - m_err.SetError(UINT_MAX, DNBError::Generic); + return true; } - return m_err.Success(); + DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x can't continue, ignoring...", m_task.TaskPort()); + return false; } bool @@ -331,8 +323,9 @@ DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() state = %s", DNBStateAsString(state)); errno = 0; ::ptrace (PT_KILL, m_pid, 0, 0); - m_err.SetErrorToErrno(); - DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", m_err.Error(), m_err.AsString()); + DNBError err; + err.SetErrorToErrno(); + DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", err.Error(), err.AsString()); PrivateResume (DNBThreadResumeActions (eStateRunning, 0)); return true; } @@ -344,7 +337,6 @@ nub_state_t state = GetState(); if (::kill (ProcessID(), signal) == 0) { - m_err.Clear(); // If we were running and we have a timeout, wait for the signal to stop if (IsRunning(state) && timeout_abstime) { @@ -355,13 +347,11 @@ return !IsRunning (state); } DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) not waiting...", signal, timeout_abstime); + return true; } - else - { - m_err.SetError(errno, DNBError::POSIX); - m_err.LogThreadedIfError("kill (pid = %d, signo = %i)", ProcessID(), signal); - } - return m_err.Success(); + DNBError err(errno, DNBError::POSIX); + err.LogThreadedIfError("kill (pid = %d, signo = %i)", ProcessID(), signal); + return false; } @@ -423,9 +413,9 @@ errno = 0; nub_process_t pid = m_pid; ::ptrace (PT_DETACH, pid, (caddr_t)1, 0); - m_err.SetError (errno, DNBError::POSIX); - if (DNBLogCheckLogBit(LOG_PROCESS) || m_err.Fail()) - m_err.LogThreaded("::ptrace (PT_DETACH, %u, (caddr_t)1, 0)", pid); + DNBError err(errno, DNBError::POSIX); + if (DNBLogCheckLogBit(LOG_PROCESS) || err.Fail()) + err.LogThreaded("::ptrace (PT_DETACH, %u, (caddr_t)1, 0)", pid); // Resume our task m_task.Resume(); @@ -590,9 +580,9 @@ thread_actions.SetSignalHandledForThread (pos->state.thread_port); } - m_err = pos->Reply(this, thread_reply_signal); + DNBError err (pos->Reply(this, thread_reply_signal)); if (DNBLogCheckLogBit(LOG_EXCEPTIONS)) - m_err.LogThreadedIfError("Error replying to exception"); + err.LogThreadedIfError("Error replying to exception"); } // Erase all exception message as we should have used and replied @@ -620,8 +610,7 @@ SetState (eStateRunning); // Now resume our task. - m_err = m_task.Resume(); - + m_task.Resume(); } nub_break_t @@ -1138,7 +1127,8 @@ nub_addr_t MachProcess::GetDYLDAllImageInfosAddress () { - return m_task.GetDYLDAllImageInfosAddress(m_err); + DNBError err; + return m_task.GetDYLDAllImageInfosAddress(err); } size_t @@ -1279,11 +1269,12 @@ Clear(); if (pid != 0) { + DNBError err; // Make sure the process exists... if (::getpgid (pid) < 0) { - m_err.SetErrorToErrno(); - const char *err_cstr = m_err.AsString(); + err.SetErrorToErrno(); + const char *err_cstr = err.AsString(); ::snprintf (err_str, err_len, "%s", err_cstr ? err_cstr : "No such process"); return INVALID_NUB_PROCESS; } @@ -1295,9 +1286,9 @@ if (IsSBProcess(pid)) m_flags |= eMachProcessFlagsUsingSBS; #endif - if (!m_task.StartExceptionThread(m_err)) + if (!m_task.StartExceptionThread(err)) { - const char *err_cstr = m_err.AsString(); + const char *err_cstr = err.AsString(); ::snprintf (err_str, err_len, "%s", err_cstr ? err_cstr : "unable to start the exception thread"); DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid); m_pid = INVALID_NUB_PROCESS; @@ -1305,14 +1296,12 @@ } errno = 0; - int err = ptrace (PT_ATTACHEXC, pid, 0, 0); - - if (err < 0) - m_err.SetError(errno); + if (::ptrace (PT_ATTACHEXC, pid, 0, 0)) + err.SetError(errno); else - m_err.Clear(); + err.Clear(); - if (m_err.Success()) + if (err.Success()) { m_flags |= eMachProcessFlagsAttached; // Sleep a bit to let the exception get received and set our process status @@ -1323,7 +1312,7 @@ } else { - ::snprintf (err_str, err_len, "%s", m_err.AsString()); + ::snprintf (err_str, err_len, "%s", err.AsString()); DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid); } } @@ -1525,11 +1514,11 @@ for (i=0; (arg = argv[i]) != NULL; i++) m_args.push_back(arg); - m_task.StartExceptionThread(m_err); - if (m_err.Fail()) + m_task.StartExceptionThread(launch_err); + if (launch_err.Fail()) { - if (m_err.AsString() == NULL) - m_err.SetErrorString("unable to start the exception thread"); + if (launch_err.AsString() == NULL) + launch_err.SetErrorString("unable to start the exception thread"); ::ptrace (PT_KILL, m_pid, 0, 0); m_pid = INVALID_NUB_PROCESS; return INVALID_NUB_PROCESS; Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=109930&r1=109929&r2=109930&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Fri Jul 30 18:14:42 2010 @@ -161,8 +161,6 @@ return state == eStateStopped; } - const DNBError& GetLastError () const { return m_err; } - bool GetExitStatus(int* status) { if (GetState() == eStateExited) @@ -246,7 +244,6 @@ PThreadMutex m_exception_messages_mutex; // Multithreaded protection for m_exception_messages MachThreadList m_threadList; // A list of threads that is maintained/updated after each stop - DNBError m_err; // The last error for any transaction nub_state_t m_state; // The state of our process PThreadMutex m_state_mutex; // Multithreaded protection for m_state PThreadEvent m_events; // Process related events in the child processes lifetime can be waited upon Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp?rev=109930&r1=109929&r2=109930&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp Fri Jul 30 18:14:42 2010 @@ -226,13 +226,10 @@ char str[1024]; ::snprintf (str, sizeof(str), - "::task_for_pid ( task_self, pid = %d, task => TASK_NULL (0x%4.4x) ) uid=%u, euid=%u gid=%u egid=%u (%s)", + "::task_for_pid ( target_tport = 0x%4.4x, pid = %d, &task ) => err = 0x%8.8x (%s)", + task_self, pid, - task, - getuid(), - geteuid(), - getgid(), - getegid(), + err.Error(), err.AsString() ? err.AsString() : "success"); if (err.Fail()) err.SetErrorString(str); Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=109930&r1=109929&r2=109930&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/debugserver.cpp (original) +++ lldb/trunk/tools/debugserver/source/debugserver.cpp Fri Jul 30 18:14:42 2010 @@ -216,7 +216,7 @@ if (pid == INVALID_NUB_PROCESS && strlen(launch_err_str) > 0) { - DNBLogThreaded ("%s DNBProcessLaunch() returned error: '%s'", __FUNCTION__); + DNBLogThreaded ("%s DNBProcessLaunch() returned error: '%s'", __FUNCTION__, launch_err_str); ctx.LaunchStatus().SetError(-1, DNBError::Generic); ctx.LaunchStatus().SetErrorString(launch_err_str); } @@ -676,6 +676,7 @@ // signal (SIGINT, signal_handler); signal (SIGPIPE, signal_handler); + signal (SIGHUP, signal_handler); int i; int attach_pid = INVALID_NUB_PROCESS; From scallanan at apple.com Fri Jul 30 20:32:05 2010 From: scallanan at apple.com (Sean Callanan) Date: Sat, 31 Jul 2010 01:32:05 -0000 Subject: [Lldb-commits] [lldb] r109938 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/IRForTarget.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp source/Target/ThreadPlanCallFunction.cpp Message-ID: <20100731013205.96B182A6C12C@llvm.org> Author: spyffe Date: Fri Jul 30 20:32:05 2010 New Revision: 109938 URL: http://llvm.org/viewvc/llvm-project?rev=109938&view=rev Log: Added support for rewriting objc_msgSend so we can call Objective-C methods from expressions. Also added some more logging to the function-calling thread plan so that we can see the registers when a function finishes. Also documented things maybe a bit better. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=109938&r1=109937&r2=109938&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Fri Jul 30 20:32:05 2010 @@ -29,33 +29,6 @@ namespace lldb_private { -//---------------------------------------------------------------------- -// For cases in which there are multiple classes of types that are not -// interchangeable, to allow static type checking. -//---------------------------------------------------------------------- -template class TaggedClangASTType : public ClangASTType -{ -public: - TaggedClangASTType (void *type, clang::ASTContext *ast_context) : - ClangASTType(type, ast_context) { } - - TaggedClangASTType (const TaggedClangASTType &tw) : - ClangASTType(tw) { } - - TaggedClangASTType () : - ClangASTType() { } - - ~TaggedClangASTType() { } - - const TaggedClangASTType & - operator= (const TaggedClangASTType &tw) - { - ClangASTType::operator= (tw); - return *this; - } -}; - - class Error; class Function; class NameSearchContext; @@ -92,6 +65,9 @@ llvm::Value**& value, uint64_t &ptr); + bool GetFunctionAddress (const char *name, + uint64_t &ptr); + // Interface for DwarfExpression Value *GetValueForIndex (uint32_t index); @@ -112,8 +88,8 @@ void GetDecls (NameSearchContext &context, const char *name); private: - typedef TaggedClangASTType<0> TypeFromParser; - typedef TaggedClangASTType<1> TypeFromUser; + typedef TaggedASTType<0> TypeFromParser; + typedef TaggedASTType<1> TypeFromUser; struct Tuple { Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=109938&r1=109937&r2=109938&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Fri Jul 30 20:32:05 2010 @@ -15,7 +15,9 @@ namespace llvm { class BasicBlock; class CallInst; + class Constant; class Function; + class Instruction; class Module; class TargetData; class Value; @@ -37,22 +39,36 @@ llvm::PassManagerType T = llvm::PMT_ModulePassManager); llvm::PassManagerType getPotentialPassManagerType() const; private: + // pass to rewrite Objective-C method calls to use the runtime function + // sel_registerName + bool RewriteObjCSelector(llvm::Instruction* selector_load, + llvm::Module &M); + bool rewriteObjCSelectors(llvm::Module &M, + llvm::BasicBlock &BB); + + // pass to register referenced variables and redirect functions at their + // targets in the debugged process bool MaybeHandleVariable(llvm::Module &M, llvm::Value *V, bool Store); bool MaybeHandleCall(llvm::Module &M, llvm::CallInst *C); - bool runOnBasicBlock(llvm::Module &M, - llvm::BasicBlock &BB); + bool resolveExternals(llvm::Module &M, + llvm::BasicBlock &BB); + + // pass to find references to guard variables and excise them bool removeGuards(llvm::Module &M, llvm::BasicBlock &BB); + + // pass to replace all identified variables with references to members of + // the argument struct bool replaceVariables(llvm::Module &M, - llvm::Function *F); - bool replaceFunctions(llvm::Module &M, - llvm::Function *F); + llvm::Function &F); lldb_private::ClangExpressionDeclMap *m_decl_map; const llvm::TargetData *m_target_data; + + llvm::Constant *m_sel_registerName; }; -#endif \ No newline at end of file +#endif Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=109938&r1=109937&r2=109938&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Jul 30 20:32:05 2010 @@ -204,6 +204,39 @@ return false; } +bool +ClangExpressionDeclMap::GetFunctionAddress (const char *name, + uint64_t &ptr) +{ + // Back out in all cases where we're not fully initialized + if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx) + return false; + + ConstString name_cs(name); + SymbolContextList sym_ctxs; + + m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs); + + if (!sym_ctxs.GetSize()) + return false; + + SymbolContext sym_ctx; + sym_ctxs.GetContextAtIndex(0, sym_ctx); + + const Address *fun_address; + + if (sym_ctx.function) + fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress(); + else if (sym_ctx.symbol) + fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress(); + else + return false; + + ptr = fun_address->GetLoadAddress(m_exe_ctx->process); + + return true; +} + // Interface for DwarfExpression lldb_private::Value *ClangExpressionDeclMap::GetValueForIndex (uint32_t index) @@ -547,7 +580,7 @@ if (type->GetASTContext() == var->GetType()->GetClangAST()) { - if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type, var->GetType()->GetOpaqueClangQualType())) + if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType())) continue; } else @@ -778,7 +811,7 @@ m_tuples.push_back(tuple); if (log) - log->PutCString("Found variable"); + log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl); } void @@ -851,5 +884,5 @@ m_tuples.push_back(tuple); if (log) - log->PutCString("Found function"); + log->Printf("Found function %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), fun_decl); } Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=109938&r1=109937&r2=109938&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Fri Jul 30 20:32:05 2010 @@ -32,7 +32,8 @@ const TargetData *target_data) : ModulePass(pid), m_decl_map(decl_map), - m_target_data(target_data) + m_target_data(target_data), + m_sel_registerName(NULL) { } @@ -40,6 +41,165 @@ { } +static bool isObjCSelectorRef(Value *V) +{ + GlobalVariable *GV = dyn_cast(V); + + if (!GV || !GV->hasName() || !GV->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_")) + return false; + + return true; +} + +bool +IRForTarget::RewriteObjCSelector(Instruction* selector_load, + Module &M) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + LoadInst *load = dyn_cast(selector_load); + + if (!load) + return false; + + // Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as + // + // %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; + // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; + // + // where %obj is the object pointer and %tmp is the selector. + // + // @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_METH_VAR_NAME_". + // @"\01L_OBJC_METH_VAR_NAME_" contains the string. + + // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target + + GlobalVariable *_objc_selector_references_ = dyn_cast(load->getPointerOperand()); + + if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer()) + return false; + + Constant *osr_initializer = _objc_selector_references_->getInitializer(); + + ConstantExpr *osr_initializer_expr = dyn_cast(osr_initializer); + + if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr) + return false; + + Value *osr_initializer_base = osr_initializer_expr->getOperand(0); + + if (!osr_initializer_base) + return false; + + // Find the string's initializer (a ConstantArray) and get the string from it + + GlobalVariable *_objc_meth_var_name_ = dyn_cast(osr_initializer_base); + + if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer()) + return false; + + Constant *omvn_initializer = _objc_meth_var_name_->getInitializer(); + + ConstantArray *omvn_initializer_array = dyn_cast(omvn_initializer); + + if (!omvn_initializer_array->isString()) + return false; + + std::string omvn_initializer_string = omvn_initializer_array->getAsString(); + + if (log) + log->Printf("Found Objective-C selector reference %s", omvn_initializer_string.c_str()); + + // Construct a call to sel_registerName + + if (!m_sel_registerName) + { + uint64_t srN_addr; + + if (!m_decl_map->GetFunctionAddress("sel_registerName", srN_addr)) + return false; + + // Build the function type: struct objc_selector *sel_registerName(uint8_t*) + + // The below code would be "more correct," but in actuality what's required is uint8_t* + //Type *sel_type = StructType::get(M.getContext()); + //Type *sel_ptr_type = PointerType::getUnqual(sel_type); + const Type *sel_ptr_type = Type::getInt8PtrTy(M.getContext()); + + std::vector srN_arg_types; + srN_arg_types.push_back(Type::getInt8PtrTy(M.getContext())); + llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false); + + // Build the constant containing the pointer to the function + const IntegerType *intptr_ty = Type::getIntNTy(M.getContext(), + (M.getPointerSize() == Module::Pointer64) ? 64 : 32); + PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type); + Constant *srN_addr_int = ConstantInt::get(intptr_ty, srN_addr, false); + m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty); + } + + SmallVector srN_arguments; + + Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(M.getContext())); + + srN_arguments.push_back(omvn_pointer); + + CallInst *srN_call = CallInst::Create(m_sel_registerName, + srN_arguments.begin(), + srN_arguments.end(), + "srN", + selector_load); + + // Replace the load with the call in all users + + selector_load->replaceAllUsesWith(srN_call); + + selector_load->eraseFromParent(); + + return true; +} + +bool +IRForTarget::rewriteObjCSelectors(Module &M, + BasicBlock &BB) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + BasicBlock::iterator ii; + + typedef SmallVector InstrList; + typedef InstrList::iterator InstrIterator; + + InstrList selector_loads; + + for (ii = BB.begin(); + ii != BB.end(); + ++ii) + { + Instruction &inst = *ii; + + if (LoadInst *load = dyn_cast(&inst)) + if (isObjCSelectorRef(load->getPointerOperand())) + selector_loads.push_back(&inst); + } + + InstrIterator iter; + + for (iter = selector_loads.begin(); + iter != selector_loads.end(); + ++iter) + { + if (!RewriteObjCSelector(*iter, M)) + { + if(log) + log->PutCString("Couldn't rewrite a reference to an Objective-C selector"); + return false; + } + } + + return true; +} + static clang::NamedDecl * DeclForGlobalValue(Module &module, GlobalValue *global_value) @@ -85,10 +245,22 @@ Value *V, bool Store) { + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + if (GlobalVariable *global_variable = dyn_cast(V)) - { + { clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable); + if (!named_decl) + { + if (isObjCSelectorRef(V)) + return true; + + if (log) + log->Printf("Found global variable %s without metadata", global_variable->getName().str().c_str()); + return false; + } + std::string name = named_decl->getName().str(); void *qual_type = NULL; @@ -134,28 +306,34 @@ return true; clang::NamedDecl *fun_decl = DeclForGlobalValue(M, fun); + uint64_t fun_addr; + Value **fun_value_ptr = NULL; - if (!fun_decl) + if (fun_decl) { - if (log) - log->Printf("Function %s wasn't in the metadata", fun->getName().str().c_str()); - return false; + if (!m_decl_map->GetFunctionInfo(fun_decl, fun_value_ptr, fun_addr)) + { + if (log) + log->Printf("Function %s had no address", fun_decl->getNameAsCString()); + return false; + } } - - uint64_t fun_addr; - Value **fun_value_ptr; - - if (!m_decl_map->GetFunctionInfo(fun_decl, fun_value_ptr, fun_addr)) + else { - if (log) - log->Printf("Function %s had no address", fun_decl->getNameAsCString()); - return false; + if (!m_decl_map->GetFunctionAddress(fun->getName().str().c_str(), fun_addr)) + { + if (log) + log->Printf("Metadataless function %s had no address", fun->getName().str().c_str()); + return false; + } } if (log) - log->Printf("Found %s at %llx", fun_decl->getNameAsCString(), fun_addr); + log->Printf("Found %s at %llx", fun->getName().str().c_str(), fun_addr); - if (!*fun_value_ptr) + Value *fun_addr_ptr; + + if (!fun_value_ptr || !*fun_value_ptr) { std::vector params; @@ -165,17 +343,22 @@ FunctionType *fun_ty = FunctionType::get(intptr_ty, params, true); PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); Constant *fun_addr_int = ConstantInt::get(intptr_ty, fun_addr, false); - Constant *fun_addr_ptr = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); - *fun_value_ptr = fun_addr_ptr; + fun_addr_ptr = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); + + if (fun_value_ptr) + *fun_value_ptr = fun_addr_ptr; } + + if (fun_value_ptr) + fun_addr_ptr = *fun_value_ptr; - C->setCalledFunction(*fun_value_ptr); + C->setCalledFunction(fun_addr_ptr); return true; } bool -IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB) +IRForTarget::resolveExternals(Module &M, BasicBlock &BB) { ///////////////////////////////////////////////////////////////////////// // Prepare the current basic block for execution in the remote process @@ -192,7 +375,7 @@ if (LoadInst *load = dyn_cast(&inst)) if (!MaybeHandleVariable(M, load->getPointerOperand(), false)) return false; - + if (StoreInst *store = dyn_cast(&inst)) if (!MaybeHandleVariable(M, store->getPointerOperand(), true)) return false; @@ -409,7 +592,7 @@ } bool -IRForTarget::replaceVariables(Module &M, Function *F) +IRForTarget::replaceVariables(Module &M, Function &F) { lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); @@ -427,9 +610,9 @@ if (!m_decl_map->GetStructInfo (num_elements, size, alignment)) return false; - Function::arg_iterator iter(F->getArgumentList().begin()); + Function::arg_iterator iter(F.getArgumentList().begin()); - if (iter == F->getArgumentList().end()) + if (iter == F.getArgumentList().end()) return false; Argument *argument = iter; @@ -440,7 +623,7 @@ if (log) log->Printf("Arg: %s", PrintValue(argument).c_str()); - BasicBlock &entry_block(F->getEntryBlock()); + BasicBlock &entry_block(F.getEntryBlock()); Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg()); if (!first_entry_instruction) @@ -500,21 +683,29 @@ Function::iterator bbi; + ////////////////////////////////// + // Run basic-block level passes + // + for (bbi = function->begin(); bbi != function->end(); ++bbi) { - if (!runOnBasicBlock(M, *bbi)) + if (!rewriteObjCSelectors(M, *bbi)) + return false; + + if (!resolveExternals(M, *bbi)) return false; if (!removeGuards(M, *bbi)) return false; } - // TEMPORARY FOR DEBUGGING - M.dump(); + /////////////////////////////// + // Run function-level passes + // - if (!replaceVariables(M, function)) + if (!replaceVariables(M, *function)) return false; if (log) Modified: lldb/trunk/source/Target/ThreadPlanCallFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallFunction.cpp?rev=109938&r1=109937&r2=109938&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanCallFunction.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Fri Jul 30 20:32:05 2010 @@ -181,6 +181,25 @@ { if (PlanExplainsStop()) { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + + if (log) + { + RegisterContext *reg_ctx = m_thread.GetRegisterContext(); + + log->PutCString("Function completed. Register state was:"); + + for (uint32_t register_index = 0, num_registers = reg_ctx->GetRegisterCount(); + register_index < num_registers; + ++register_index) + { + const char *register_name = reg_ctx->GetRegisterName(register_index); + uint64_t register_value = reg_ctx->ReadRegisterAsUnsigned(register_index, LLDB_INVALID_ADDRESS); + + log->Printf(" %s = 0x%llx", register_name, register_value); + } + } + m_thread.RestoreSaveFrameZero(m_register_backup); m_thread.ClearStackFrames(); SetPlanComplete();