diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Commands/CommandObjectType.cpp | 415 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectType.h | 42 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 37 | ||||
-rw-r--r-- | lldb/source/Core/FormatManager.cpp | 69 | ||||
-rw-r--r-- | lldb/source/Interpreter/Args.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTType.cpp | 62 |
7 files changed, 613 insertions, 23 deletions
diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp new file mode 100644 index 00000000000..3f376bd437a --- /dev/null +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -0,0 +1,415 @@ +//===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectType.h" + +// C Includes +// C++ Includes + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/Options.h" + +using namespace lldb; +using namespace lldb_private; + +//------------------------------------------------------------------------- +// CommandObjectTypeAdd +//------------------------------------------------------------------------- + +class CommandObjectTypeAdd : public CommandObject +{ + +private: + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter) + { + } + + virtual + ~CommandOptions (){} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + bool success; + + switch (short_option) + { + case 'c': + m_cascade = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_cascade = true; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + bool m_cascade; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + +public: + CommandObjectTypeAdd (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type format add", + "Add a new formatting style for a type.", + NULL), m_options (interpreter) + { + CommandArgumentEntry format_arg; + CommandArgumentData format_style_arg; + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + format_style_arg.arg_type = eArgTypeFormat; + format_style_arg.arg_repetition = eArgRepeatPlain; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlus; + + format_arg.push_back (format_style_arg); + type_arg.push_back (type_style_arg); + + m_arguments.push_back (format_arg); + m_arguments.push_back (type_arg); + } + + ~CommandObjectTypeAdd () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + if (argc < 2) + { + result.AppendErrorWithFormat ("%s takes two or more args.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const char* formatA = command.GetArgumentAtIndex(0); + ConstString formatCS(formatA); + const char* formatU = formatCS.GetCString(); + lldb::Format format; + uint32_t byte_size_ptr; + Error fmt_error = Args::StringToFormat(formatU, format, &byte_size_ptr); + + if(fmt_error.Fail()) { + result.AppendError(fmt_error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + // now I have a valid format, let's add it to every type + + for(int i = 1; i < argc; i++) { + const char* typeA = command.GetArgumentAtIndex(i); + ConstString typeCS(typeA); + Debugger::AddFormatForType(typeCS, format, m_options.m_cascade); + } + + + return result.Succeeded(); + } + +}; + +OptionDefinition +CommandObjectTypeAdd::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "cascade", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + + +//------------------------------------------------------------------------- +// CommandObjectTypeDelete +//------------------------------------------------------------------------- + +class CommandObjectTypeDelete : public CommandObject +{ +public: + CommandObjectTypeDelete (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type format delete", + "Delete an existing formatting style for a type.", + NULL) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlain; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + + } + + ~CommandObjectTypeDelete () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + if (argc != 1) + { + result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const char* typeA = command.GetArgumentAtIndex(0); + ConstString typeCS(typeA); + + if(Debugger::DeleteFormatForType(typeCS)) + return result.Succeeded(); + else + { + result.AppendErrorWithFormat ("no custom format for %s.\n", typeA); + result.SetStatus(eReturnStatusFailed); + return false; + } + + } + +}; + +//------------------------------------------------------------------------- +// CommandObjectTypeList +//------------------------------------------------------------------------- + +bool CommandObjectTypeList_LoopCallback(void* pt2self, const char* type, lldb::Format format, bool cascade); + +class CommandObjectTypeList; + +struct CommandObjectTypeList_LoopCallbackParam { + CommandObjectTypeList* self; + CommandReturnObject* result; + RegularExpression* regex; + CommandObjectTypeList_LoopCallbackParam(CommandObjectTypeList* S, CommandReturnObject* R, + RegularExpression* X = NULL) : self(S), result(R), regex(X) {} +}; + +class CommandObjectTypeList : public CommandObject +{ +public: + CommandObjectTypeList (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type format list", + "Show a list of current formatting styles.", + NULL) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatOptional; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + } + + ~CommandObjectTypeList () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + CommandObjectTypeList_LoopCallbackParam *param; + + if (argc == 1) { + RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); + regex->Compile(command.GetArgumentAtIndex(0)); + param = new CommandObjectTypeList_LoopCallbackParam(this,&result,regex); + } + else + param = new CommandObjectTypeList_LoopCallbackParam(this,&result); + Debugger::LoopThroughFormatList(CommandObjectTypeList_LoopCallback, param); + delete param; + return result.Succeeded(); + } + +private: + + bool + LoopCallback ( + const char* type, + lldb::Format format, + bool cascade, + RegularExpression* regex, + CommandReturnObject *result + ) + { + if(regex && !regex->Execute(type)) return true; + Stream &ostrm = result->GetOutputStream(); + ostrm.Printf("(%s) %scascading ",type, cascade ? "" : "not "); + switch(format) { + case eFormatBytes: + ostrm.Printf("y\n"); + break; + case eFormatBytesWithASCII: + ostrm.Printf("Y\n"); + break; + case eFormatBinary: + ostrm.Printf("b\n"); + break; + case eFormatBoolean: + ostrm.Printf("B\n"); + break; + case eFormatCharArray: + ostrm.Printf("a\n"); + break; + case eFormatChar: + ostrm.Printf("c\n"); + break; + case eFormatCharPrintable: + ostrm.Printf("C\n"); + break; + case eFormatOctal: + ostrm.Printf("o\n"); + break; + case eFormatOSType: + ostrm.Printf("O\n"); + break; + case eFormatDecimal: + ostrm.Printf("i or d\n"); + break; + case eFormatComplexInteger: + ostrm.Printf("I\n"); + break; + case eFormatUnsigned: + ostrm.Printf("u\n"); + break; + case eFormatHex: + ostrm.Printf("x\n"); + break; + case eFormatComplex: + ostrm.Printf("X\n"); + break; + case eFormatFloat: + ostrm.Printf("f e or g\n"); + break; + case eFormatPointer: + ostrm.Printf("p\n"); + break; + case eFormatCString: + ostrm.Printf("s\n"); + break; + default: + ostrm.Printf("other\n"); + break; + } + return true; + } + + friend bool CommandObjectTypeList_LoopCallback(void* pt2self, const char* type, lldb::Format format, bool cascade); + +}; + +bool +CommandObjectTypeList_LoopCallback ( + void* pt2self, + const char* type, + lldb::Format format, + bool cascade) +{ + CommandObjectTypeList_LoopCallbackParam* param = (CommandObjectTypeList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(type, format, cascade, param->regex, param->result); +} + +class CommandObjectTypeFormat : public CommandObjectMultiword +{ +public: + CommandObjectTypeFormat (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "type format", + "A set of commands for editing variable display options", + "type format [<sub-command-options>] ") + { + LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeAdd (interpreter))); + LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeDelete (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeList (interpreter))); + } + + + ~CommandObjectTypeFormat () + { + } +}; + +//------------------------------------------------------------------------- +// CommandObjectType +//------------------------------------------------------------------------- + +CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "type", + "A set of commands for operating on the type system", + "type [<sub-command-options>]") +{ + LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); +} + + +CommandObjectType::~CommandObjectType () +{ +} + + diff --git a/lldb/source/Commands/CommandObjectType.h b/lldb/source/Commands/CommandObjectType.h new file mode 100644 index 00000000000..994d1fca049 --- /dev/null +++ b/lldb/source/Commands/CommandObjectType.h @@ -0,0 +1,42 @@ +//===-- CommandObjectType.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObjectType_h_ +#define liblldb_CommandObjectType_h_ + +// C Includes +// C++ Includes + + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-types.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" + +namespace lldb_private { + +//------------------------------------------------------------------------- +// CommandObjectMultiwordBreakpoint +//------------------------------------------------------------------------- + +class CommandObjectType : public CommandObjectMultiword +{ +public: + CommandObjectType (CommandInterpreter &interpreter); + + virtual + ~CommandObjectType (); +}; + + + +} // namespace lldb_private + +#endif // liblldb_CommandObjectType_h_ diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index ba43411dfaf..b7be1715ca9 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -7,9 +7,13 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Core/Debugger.h" + +#include <map> + #include "lldb/lldb-private.h" #include "lldb/Core/ConnectionFileDescriptor.h" -#include "lldb/Core/Debugger.h" +#include "lldb/Core/FormatManager.h" #include "lldb/Core/InputReader.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/State.h" @@ -1309,6 +1313,37 @@ Debugger::FormatPrompt return success; } + +static FormatManager& +GetFormatManager() { + static FormatManager g_format_manager; + return g_format_manager; +} + +bool +Debugger::GetFormatForType (const ConstString &type, lldb::Format& format, bool& cascade) +{ + return GetFormatManager().GetFormatForType(type, format, cascade); +} + +void +Debugger::AddFormatForType (const ConstString &type, lldb::Format format, bool cascade) +{ + GetFormatManager().AddFormatForType(type,format, cascade); +} + +bool +Debugger::DeleteFormatForType (const ConstString &type) +{ + return GetFormatManager().DeleteFormatForType(type); +} + +void +Debugger::LoopThroughFormatList (FormatCallback cback, void* param) +{ + return GetFormatManager().LoopThroughFormatList(cback, param); +} + #pragma mark Debugger::SettingsController //-------------------------------------------------- diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp new file mode 100644 index 00000000000..bbbf0777185 --- /dev/null +++ b/lldb/source/Core/FormatManager.cpp @@ -0,0 +1,69 @@ +//===-- FormatManager.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/FormatManager.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +using namespace lldb; +using namespace lldb_private; + +bool FormatManager::GetFormatForType (const ConstString &type, lldb::Format& format, bool& cascade) +{ + Mutex::Locker locker (m_format_map_mutex); + FormatMap& fmtmap = m_format_map; + FormatMap::iterator iter = fmtmap.find(type.GetCString()); + if(iter == fmtmap.end()) + return false; + else { + format = iter->second.FormatStyle; + cascade = iter->second.Cascades; + return true; + } +} + +void FormatManager::AddFormatForType (const ConstString &type, lldb::Format format, bool cascade) +{ + format_entry_t entry(format, cascade); + Mutex::Locker locker (m_format_map_mutex); + FormatMap& fmtmap = m_format_map; + fmtmap[type.GetCString()] = entry; +} + +bool FormatManager::DeleteFormatForType (const ConstString &type) +{ + Mutex::Locker locker (m_format_map_mutex); + FormatMap& fmtmap = m_format_map; + const char* typeCS = type.GetCString(); + FormatMap::iterator iter = fmtmap.find(typeCS); + if (iter == fmtmap.end()) + return false; + else { + fmtmap.erase(typeCS); + return true; + } +} + +void FormatManager::LoopThroughFormatList (FormatCallback cback, void* param) +{ + Mutex::Locker locker (m_format_map_mutex); + FormatMap& fmtmap = m_format_map; + FormatIterator iter = fmtmap.begin(); + while(iter != fmtmap.end()) { + const char* type = iter->first; + lldb::Format format = iter->second.FormatStyle; + bool cascade = iter->second.Cascades; + if(!cback(param, type,format, cascade)) break; + iter++; + } +} + diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp index 1913132fc83..e3fdb0fba8d 100644 --- a/lldb/source/Interpreter/Args.cpp +++ b/lldb/source/Interpreter/Args.cpp @@ -941,7 +941,7 @@ Args::StringToFormat " f - float\n" " g - float\n" " i - signed decimal\n" - " i - complex integer\n" + " I - complex integer\n" " o - octal\n" " O - OSType\n" " p - pointer\n" diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index d5f04020df1..5693e1d6ef9 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -13,13 +13,14 @@ #include <getopt.h> #include <stdlib.h> +#include "CommandObjectScript.h" +#include "CommandObjectRegexCommand.h" + #include "../Commands/CommandObjectApropos.h" #include "../Commands/CommandObjectArgs.h" #include "../Commands/CommandObjectBreakpoint.h" -//#include "../Commands/CommandObjectCall.h" #include "../Commands/CommandObjectDisassemble.h" #include "../Commands/CommandObjectExpression.h" -//#include "../Commands/CommandObjectFile.h" #include "../Commands/CommandObjectFrame.h" #include "../Commands/CommandObjectHelp.h" #include "../Commands/CommandObjectLog.h" @@ -27,15 +28,14 @@ #include "../Commands/CommandObjectPlatform.h" #include "../Commands/CommandObjectProcess.h" #include "../Commands/CommandObjectQuit.h" -#include "lldb/Interpreter/CommandObjectRegexCommand.h" #include "../Commands/CommandObjectRegister.h" -#include "CommandObjectScript.h" #include "../Commands/CommandObjectSettings.h" #include "../Commands/CommandObjectSource.h" #include "../Commands/CommandObjectCommands.h" #include "../Commands/CommandObjectSyntax.h" #include "../Commands/CommandObjectTarget.h" #include "../Commands/CommandObjectThread.h" +#include "../Commands/CommandObjectType.h" #include "../Commands/CommandObjectVersion.h" #include "lldb/Interpreter/Args.h" @@ -261,6 +261,7 @@ CommandInterpreter::LoadCommandDictionary () m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); + m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this)); m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this)); std::auto_ptr<CommandObjectRegexCommand> diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 4a5767b2f0f..5e623a8a9e1 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/Type.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" @@ -36,6 +37,9 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" + +#include "Debugger.h" + using namespace lldb; using namespace lldb_private; @@ -55,22 +59,9 @@ ClangASTType::GetClangTypeName (clang_type_t clang_type) ConstString clang_type_name; if (clang_type) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - - const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); - if (typedef_type) - { - const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); - std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString()); - if (!clang_typedef_name.empty()) - clang_type_name.SetCString (clang_typedef_name.c_str()); - } - else - { - std::string type_name(qual_type.getAsString()); - if (!type_name.empty()) - clang_type_name.SetCString (type_name.c_str()); - } + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + return GetClangTypeName(qual_type); + } else { @@ -80,6 +71,26 @@ ClangASTType::GetClangTypeName (clang_type_t clang_type) return clang_type_name; } +ConstString +ClangASTType::GetClangTypeName (clang::QualType qual_type) +{ + ConstString clang_type_name; + const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); + if (typedef_type) + { + const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString()); + if (!clang_typedef_name.empty()) + clang_type_name.SetCString (clang_typedef_name.c_str()); + } + else + { + std::string type_name(qual_type.getAsString()); + if (!type_name.empty()) + clang_type_name.SetCString (type_name.c_str()); + } + return clang_type_name; +} clang_type_t ClangASTType::GetPointeeType () @@ -237,8 +248,25 @@ ClangASTType::GetFormat () lldb::Format ClangASTType::GetFormat (clang_type_t clang_type) { + // first of all, check for a valid format for this type itself clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - + lldb::Format format; + bool cascade; + if(Debugger::GetFormatForType(GetClangTypeName(qual_type), format, cascade)) + return format; // return it if found + + // here, I know this type does not have a direct format. two things can happen: + // 1) this is a typedef - I expand this to its parent type and look there + // 2) this is not a typedef - I use the default formatting options + const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>(); + while (typedef_type) { + qual_type = typedef_type->getDecl()->getUnderlyingType(); + std::string name = qual_type.getAsString(); + if(Debugger::GetFormatForType(GetClangTypeName(qual_type), format, cascade) && cascade) // if I have a cascading format... + return format; // ...use it + typedef_type = qual_type->getAs<clang::TypedefType>(); // try to expand another level + } + switch (qual_type->getTypeClass()) { case clang::Type::FunctionNoProto: |