diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index 05dc8eecb2c7..597beedbaf6c 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -109,7 +109,16 @@ public: uint32_t bit_size); void * - GetVoidBuiltInType(); + GetBuiltInType_void(); + + void * + GetBuiltInType_objc_id(); + + void * + GetBuiltInType_objc_Class(); + + void * + GetBuiltInType_objc_selector(); void * GetCStringType(bool is_const); @@ -387,12 +396,6 @@ public: size_t GetPointerBitSize (); - static size_t - GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type); - - static size_t - GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type); - static bool IsIntegerType (void *clang_type, bool &is_signed); diff --git a/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h index b463d13d5637..033ef5f6722c 100644 --- a/lldb/include/lldb/Symbol/ClangASTType.h +++ b/lldb/include/lldb/Symbol/ClangASTType.h @@ -75,6 +75,18 @@ public: static ConstString GetClangTypeName (void *clang_type); + uint64_t + GetClangTypeBitWidth (); + + static uint64_t + GetClangTypeBitWidth (clang::ASTContext *ast_context, void *opaque_clang_qual_type); + + size_t + GetTypeBitAlign (); + + static size_t + GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type); + void DumpValue (ExecutionContext *exe_ctx, Stream *s, @@ -142,8 +154,15 @@ public: const DataExtractor &data, uint32_t data_offset, size_t data_byte_size); - - + + void + DumpTypeDescription (Stream *s); + + static void + DumpTypeDescription (clang::ASTContext *ast_context, + void *opaque_clang_qual_type, + Stream *s); + lldb::Encoding GetEncoding (uint32_t &count); diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index b1faee654d7a..da91e1c88010 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -77,10 +77,10 @@ public: virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) = 0; virtual uint32_t FindFunctions (const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list) = 0; virtual uint32_t FindFunctions (const RegularExpression& regex, bool append, SymbolContextList& sc_list) = 0; -// virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) = 0; -// virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) = 0; + virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) = 0; +// virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0; - ObjectFile* GetObjectFile() { return m_obj_file; } + ObjectFile* GetObjectFile() { return m_obj_file; } const ObjectFile* GetObjectFile() const { return m_obj_file; } protected: ObjectFile* m_obj_file; // The object file that symbols can be extracted from. diff --git a/lldb/include/lldb/Symbol/SymbolVendor.h b/lldb/include/lldb/Symbol/SymbolVendor.h index 11922c215ce6..eb9ca1a69b93 100644 --- a/lldb/include/lldb/Symbol/SymbolVendor.h +++ b/lldb/include/lldb/Symbol/SymbolVendor.h @@ -97,28 +97,42 @@ public: SymbolContextList& sc_list); virtual uint32_t - FindGlobalVariables(const ConstString &name, - bool append, - uint32_t max_matches, - VariableList& variables); + FindGlobalVariables (const ConstString &name, + bool append, + uint32_t max_matches, + VariableList& variables); virtual uint32_t - FindGlobalVariables(const RegularExpression& regex, - bool append, - uint32_t max_matches, - VariableList& variables); + FindGlobalVariables (const RegularExpression& regex, + bool append, + uint32_t max_matches, + VariableList& variables); virtual uint32_t - FindFunctions(const ConstString &name, - uint32_t name_type_mask, - bool append, - SymbolContextList& sc_list); + FindFunctions (const ConstString &name, + uint32_t name_type_mask, + bool append, + SymbolContextList& sc_list); virtual uint32_t - FindFunctions(const RegularExpression& regex, - bool append, - SymbolContextList& sc_list); + FindFunctions (const RegularExpression& regex, + bool append, + SymbolContextList& sc_list); + virtual uint32_t + FindTypes (const SymbolContext& sc, + const ConstString &name, + bool append, + uint32_t max_matches, + TypeList& types); + +// virtual uint32_t +// FindTypes (const SymbolContext& sc, +// const RegularExpression& regex, +// bool append, +// uint32_t max_matches, +// TypeList& types); + virtual uint32_t GetNumCompileUnits(); diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 0581c424e1c8..e5011df47f9f 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -1673,7 +1673,6 @@ 26BC7C4B10F1B6C100F91463 /* Symbol */ = { isa = PBXGroup; children = ( - AF94005711C03F6500085DB9 /* SymbolVendor.cpp */, 26BC7C5510F1B6E900F91463 /* Block.h */, 26BC7F1310F1B8EC00F91463 /* Block.cpp */, 26BC7C5610F1B6E900F91463 /* ClangASTContext.h */, @@ -1703,6 +1702,7 @@ 26BC7C6210F1B6E900F91463 /* SymbolFile.h */, 26BC7F1D10F1B8EC00F91463 /* SymbolFile.cpp */, 26BC7C6310F1B6E900F91463 /* SymbolVendor.h */, + AF94005711C03F6500085DB9 /* SymbolVendor.cpp */, 26BC7C6410F1B6E900F91463 /* Symtab.h */, 26BC7F1F10F1B8EC00F91463 /* Symtab.cpp */, 49BB309511F79450001A4197 /* TaggedASTType.h */, diff --git a/lldb/scripts/build-llvm.pl b/lldb/scripts/build-llvm.pl index 7c2a896a2477..e7fe80e88557 100644 --- a/lldb/scripts/build-llvm.pl +++ b/lldb/scripts/build-llvm.pl @@ -25,7 +25,7 @@ our @llvm_clang_slices; # paths to the single architecture static libraries (arc our $llvm_configuration = $ENV{LLVM_CONFIGURATION}; -our $llvm_revision = "'{2010-07-30T08:00}'"; +our $llvm_revision = "'{2010-08-02T16: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"; @@ -231,7 +231,7 @@ sub build_llvm print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n"; my $lldb_configuration_options = ''; $llvm_configuration eq 'Release' and $lldb_configuration_options .= '--enable-optimized --disable-assertions'; - do_command ("cd '$llvm_dstroot_arch' && '$llvm_source_dir/llvm/configure' $lldb_configuration_options --enable-targets=x86,x86_64,arm --build=$arch-apple-darwin10 CC=\"$cc -arch $arch\" CXX=\"$cxx -arch $arch\"", + do_command ("cd '$llvm_dstroot_arch' && '$llvm_source_dir/llvm/configure' $lldb_configuration_options --enable-targets=x86_64,arm --build=$arch-apple-darwin10 CC=\"$cc -arch $arch\" CXX=\"$cxx -arch $arch\"", "configuring llvm build", 1); } diff --git a/lldb/source/Commands/CommandObjectArgs.cpp b/lldb/source/Commands/CommandObjectArgs.cpp index 74a7d2b04dea..a7169c5c8cf6 100644 --- a/lldb/source/Commands/CommandObjectArgs.cpp +++ b/lldb/source/Commands/CommandObjectArgs.cpp @@ -232,7 +232,7 @@ CommandObjectArgs::Execute else if (strchr (arg_type_cstr, '*')) { if (!strcmp (arg_type_cstr, "void*")) - type = ast_context.CreatePointerType (ast_context.GetVoidBuiltInType ()); + type = ast_context.CreatePointerType (ast_context.GetBuiltInType_void ()); else if (!strcmp (arg_type_cstr, "char*")) type = ast_context.GetCStringType (false); else diff --git a/lldb/source/Commands/CommandObjectImage.cpp b/lldb/source/Commands/CommandObjectImage.cpp index b6b0d2469e98..a5d1f332a9f7 100644 --- a/lldb/source/Commands/CommandObjectImage.cpp +++ b/lldb/source/Commands/CommandObjectImage.cpp @@ -201,7 +201,16 @@ DumpModuleSymbolVendor (Stream &strm, Module *module) } static bool -LookupAddressInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset) +LookupAddressInModule +( + CommandInterpreter &interpreter, + Stream &strm, + Module *module, + uint32_t resolve_mask, + lldb::addr_t raw_addr, + lldb::addr_t offset, + bool verbose +) { if (module) { @@ -234,8 +243,12 @@ LookupAddressInModule (CommandInterpreter &interpreter, Stream &strm, Module *mo strm.Indent (" Summary: "); so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); strm.EOL(); - if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext)) - strm.EOL(); + // Print out detailed address information when verbose is enabled + if (verbose) + { + if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext)) + strm.EOL(); + } strm.IndentLess(); return true; } @@ -371,6 +384,63 @@ LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *m return 0; } +static uint32_t +LookupTypeInModule +( + CommandInterpreter &interpreter, + Stream &strm, + Module *module, + const char *name_cstr, + bool name_is_regex +) +{ + if (module && name_cstr && name_cstr[0]) + { + SymbolContextList sc_list; + + SymbolVendor *symbol_vendor = module->GetSymbolVendor(); + if (symbol_vendor) + { + TypeList type_list; + uint32_t num_matches = 0; + SymbolContext sc; +// if (name_is_regex) +// { +// RegularExpression name_regex (name_cstr); +// num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list); +// } +// else +// { + ConstString name(name_cstr); + num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list); +// } + + if (num_matches) + { + strm.Indent (); + strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); + DumpFullpath (strm, &module->GetFileSpec(), 0); + strm.PutCString(":\n"); + const uint32_t num_types = type_list.GetSize(); + for (uint32_t i=0; iGetOpaqueClangQualType (); + type_sp->GetDescription (&strm, eDescriptionLevelFull, true); + } + strm.EOL(); + } + } + return num_matches; + } + } + return 0; +} + static uint32_t LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines) { @@ -1130,6 +1200,7 @@ public: eLookupTypeSymbol, eLookupTypeFileLine, // Line is optional eLookupTypeFunction, + eLookupTypeType, kNumLookupTypes }; @@ -1198,6 +1269,15 @@ public: m_type = eLookupTypeFunction; break; + case 't': + m_str = option_arg; + m_type = eLookupTypeType; + break; + + case 'v': + m_verbose = 1; + break; + case 'r': m_use_regex = true; break; @@ -1218,6 +1298,7 @@ public: m_line_number = 0; m_use_regex = false; m_check_inlines = true; + m_verbose = false; } const lldb::OptionDefinition* @@ -1237,6 +1318,8 @@ public: uint32_t m_line_number; // Line number for file+line lookups bool m_use_regex; // Name lookups in m_str are regular expressions. bool m_check_inlines;// Check for inline entries when looking up by file/line. + bool m_verbose; // Enable verbose lookup info + }; CommandObjectImageLookup () : @@ -1268,7 +1351,13 @@ public: case eLookupTypeAddress: if (m_options.m_addr != LLDB_INVALID_ADDRESS) { - if (LookupAddressInModule (interpreter, result.GetOutputStream(), module, eSymbolContextEverything, m_options.m_addr, m_options.m_offset)) + if (LookupAddressInModule (interpreter, + result.GetOutputStream(), + module, + eSymbolContextEverything, + m_options.m_addr, + m_options.m_offset, + m_options.m_verbose)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; @@ -1319,6 +1408,21 @@ public: } break; + case eLookupTypeType: + if (!m_options.m_str.empty()) + { + if (LookupTypeInModule (interpreter, + result.GetOutputStream(), + module, + m_options.m_str.c_str(), + m_options.m_use_regex)) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + } + break; + default: m_options.GenerateOptionUsage (result.GetErrorStream(), this); syntax_error = true; @@ -1428,14 +1532,16 @@ protected: lldb::OptionDefinition CommandObjectImageLookup::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "", "Lookup an address in one or more executable images."}, -{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, "", "When looking up an address subtract from any addresses before doing the lookup."}, -{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, "", "Lookup a symbol by name in the symbol tables in one or more executable images."}, -{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The argument for name lookups are regular expressions."}, -{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, "", "Lookup a file by fullpath or basename in one or more executable images."}, -{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, "", "Lookup a line number in a file (must be used in conjunction with --file)."}, -{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."}, -{ LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, "", "Lookup a function by name in the debug symbols in one or more executable images."}, +{ LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, "", "Lookup an address in one or more executable images."}, +{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, "", "When looking up an address subtract from any addresses before doing the lookup."}, +{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, "", "Lookup a symbol by name in the symbol tables in one or more executable images."}, +{ LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, NULL, "The argument for name lookups are regular expressions."}, +{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, "", "Lookup a file by fullpath or basename in one or more executable images."}, +{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, "", "Lookup a line number in a file (must be used in conjunction with --file)."}, +{ LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, NULL, "Check inline line entries (must be used in conjunction with --file)."}, +{ LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, "", "Lookup a function by name in the debug symbols in one or more executable images."}, +{ LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, "", "Lookup a type by name in the debug symbols in one or more executable images."}, +{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, NULL, "Enable verbose lookup information."}, { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } }; diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index 97595326b346..235f9b3e8331 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -712,18 +712,16 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum { lldb_private::SymbolContext sc; module->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc); - if (sc.function || sc.symbol) + if (sc.symbol) { - if (sc.function == NULL && sc.symbol != NULL) - { - // If we have just a symbol make sure it is in the right section - if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() == GetSection()) - { - sc.GetDescription(s, eDescriptionLevelBrief, process); - break; - } - } + // If we have just a symbol make sure it is in the same section + // as our address. If it isn't, then we might have just found + // the last symbol that came before the address that we are + // looking up that has nothing to do with our address lookup. + if (sc.symbol->GetAddressRangePtr() && sc.symbol->GetAddressRangePtr()->GetBaseAddress().GetSection() != GetSection()) + sc.symbol = NULL; } + sc.GetDescription(s, eDescriptionLevelBrief, process); } } if (fallback_style != DumpStyleInvalid) diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index 2399059b730c..a9a468880e87 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -385,7 +385,7 @@ Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr) } else { - uint64_t bit_width = ClangASTContext::GetTypeBitSize (ast_context, m_context); + uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (ast_context, m_context); byte_size = (bit_width + 7 ) / 8; } break; diff --git a/lldb/source/Expression/ClangExpression.cpp b/lldb/source/Expression/ClangExpression.cpp index 144f30a5bd4d..0ff4c38f2fcc 100644 --- a/lldb/source/Expression/ClangExpression.cpp +++ b/lldb/source/Expression/ClangExpression.cpp @@ -103,10 +103,6 @@ std::string GetBuiltinIncludePath(const char *Argv0) { } -//===----------------------------------------------------------------------===// -// Main driver -//===----------------------------------------------------------------------===// - //===----------------------------------------------------------------------===// // Main driver //===----------------------------------------------------------------------===// @@ -149,14 +145,14 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { 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; + llvm::OwningPtr P(it->instantiate()); + if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) + return 0; + return P.take(); } } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 7e733e4ce0b4..ff54250d9b7d 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -475,7 +475,7 @@ ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize, { lldb::addr_t value_addr = location_value->GetScalar().ULongLong(); - size_t bit_size = ClangASTContext::GetTypeBitSize(type.GetASTContext(), type.GetOpaqueQualType()); + size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType()); size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8); DataBufferHeap data; diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 20c97b28e072..9609cad3731a 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -2126,8 +2126,8 @@ DWARFExpression::Evaluate return false; } - uint64_t member_bit_size = ClangASTContext::GetTypeBitSize(ast_context, member_type); - uint64_t member_bit_align = ClangASTContext::GetTypeBitAlign(ast_context, member_type); + uint64_t member_bit_size = ClangASTType::GetClangTypeBitWidth(ast_context, member_type); + uint64_t member_bit_align = ClangASTType::GetTypeBitAlign(ast_context, member_type); uint64_t member_bit_incr = ((member_bit_size + member_bit_align - 1) / member_bit_align) * member_bit_align; if (member_bit_incr % 8) { @@ -2194,7 +2194,7 @@ DWARFExpression::Evaluate addr_t source_addr = (addr_t)tmp.GetScalar().ULongLong(); addr_t target_addr = (addr_t)stack.back().GetScalar().ULongLong(); - size_t byte_size = (ClangASTContext::GetTypeBitSize(ast_context, clang_type) + 7) / 8; + size_t byte_size = (ClangASTType::GetClangTypeBitWidth(ast_context, clang_type) + 7) / 8; switch (source_value_type) { diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 09cc09d024ca..49290e8afbf1 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -416,7 +416,7 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread, if (ClangASTContext::IsIntegerType (value_type, is_signed)) { - size_t bit_width = ClangASTContext::GetTypeBitSize(ast_context, value_type); + size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); ReadIntegerArgument(value->GetScalar(), bit_width, @@ -465,7 +465,7 @@ ABIMacOSX_i386::GetReturnValue (Thread &thread, if (ClangASTContext::IsIntegerType (value_type, is_signed)) { - size_t bit_width = ClangASTContext::GetTypeBitSize(ast_context, value_type); + size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->reg; unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->reg; diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index 004be60c3778..e0efd6eeb7bf 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -250,7 +250,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread, if (ClangASTContext::IsIntegerType (value_type, is_signed)) { - size_t bit_width = ClangASTContext::GetTypeBitSize(ast_context, value_type); + size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); ReadIntegerArgument(value->GetScalar(), bit_width, @@ -305,7 +305,7 @@ ABISysV_x86_64::GetReturnValue (Thread &thread, // Extract the register context so we can read arguments from registers - size_t bit_width = ClangASTContext::GetTypeBitSize(ast_context, value_type); + size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type); unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->reg; switch (bit_width) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 6a3b5487164b..2bb7a1033a42 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -430,6 +430,20 @@ ProcessGDBRemote::DoLaunch } } + // FIXME: convert this to use the new set/show variables when they are available +#if 0 + if (::getenv ("LLDB_DEBUG_DEBUGSERVER")) + { + const uint32_t attach_debugserver_secs = 10; + ::printf ("attach to debugserver (pid = %i)\n", m_debugserver_pid); + for (uint32_t i=0; i 0) -// { -// // Pass false to indicate this is a pubnames section -// m_pubtypes.reset(new DWARFDebugPubnames()); -// if (m_pubtypes.get()) -// m_pubtypes->Extract(debug_pubtypes_data); -// } -// } -// return m_pubtypes.get(); -//} -// +DWARFDebugPubnames* +SymbolFileDWARF::DebugPubtypes() +{ + if (m_pubtypes.get() == NULL) + { + Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); + const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data(); + if (debug_pubtypes_data.GetByteSize() > 0) + { + // Pass false to indicate this is a pubnames section + m_pubtypes.reset(new DWARFDebugPubnames()); + if (m_pubtypes.get()) + m_pubtypes->Extract(debug_pubtypes_data); + } + } + return m_pubtypes.get(); +} + bool SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp) @@ -1974,9 +1974,8 @@ SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, Symb return sc_list.GetSize() - original_size; } -#if 0 uint32_t -SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) +SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) { // If we aren't appending the results to this list, then clear the list if (!append) @@ -1984,54 +1983,55 @@ SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, boo // Create the pubnames information so we can quickly lookup external symbols by name DWARFDebugPubnames* pubtypes = DebugPubtypes(); + if (pubtypes) { std::vector die_offsets; if (!pubtypes->Find(name.AsCString(), false, die_offsets)) { - DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); - if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets)) +// DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); +// if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets)) return 0; } - return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); + return FindTypes(die_offsets, max_matches, types); } return 0; } -uint32_t -SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) -{ - // If we aren't appending the results to this list, then clear the list - if (!append) - types.Clear(); - - // Create the pubnames information so we can quickly lookup external symbols by name - DWARFDebugPubnames* pubtypes = DebugPubtypes(); - if (pubtypes) - { - std::vector die_offsets; - if (!pubtypes->Find(regex, die_offsets)) - { - DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); - if (pub_base_types && !pub_base_types->Find(regex, die_offsets)) - return 0; - } - - return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); - } - - return 0; -} - +//uint32_t +//SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) +//{ +// // If we aren't appending the results to this list, then clear the list +// if (!append) +// types.Clear(); +// +// // Create the pubnames information so we can quickly lookup external symbols by name +// DWARFDebugPubnames* pubtypes = DebugPubtypes(); +// if (pubtypes) +// { +// std::vector die_offsets; +// if (!pubtypes->Find(regex, die_offsets)) +// { +// DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes(); +// if (pub_base_types && !pub_base_types->Find(regex, die_offsets)) +// return 0; +// } +// +// return FindTypes(die_offsets, max_matches, encoding, udt_uid, types); +// } +// +// return 0; +//} +// uint32_t -SymbolFileDWARF::FindTypes(std::vector die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) +SymbolFileDWARF::FindTypes(std::vector die_offsets, uint32_t max_matches, TypeList& types) { // Remember how many sc_list are in the list before we search in case // we are appending the results to a variable list. - uint32_t original_size = types.Size(); + uint32_t original_size = types.GetSize(); const uint32_t num_die_offsets = die_offsets.size(); // Parse all of the types we found from the pubtypes matches @@ -2039,125 +2039,23 @@ SymbolFileDWARF::FindTypes(std::vector die_offsets, uint32_t max_ma uint32_t num_matches = 0; for (i = 0; i < num_die_offsets; ++i) { - dw_offset_t die_offset = die_offsets[i]; - DWARFCompileUnitSP cu_sp; - const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); - - assert(die != NULL); - - bool get_type_for_die = true; - if (encoding) + Type *matching_type = ResolveTypeUID (die_offsets[i]); + if (matching_type) { - // Check if this type has already been uniqued and registers with the module? - Type* type = (Type*)die->GetUserData(); - if (type != NULL && type != DIE_IS_BEING_PARSED) - { - get_type_for_die = type->GetEncoding() == encoding; - } - else - { - dw_tag_t tag = die->Tag(); - switch (encoding) - { - case Type::address: - case Type::boolean: - case Type::complex_float: - case Type::float_type: - case Type::signed_int: - case Type::signed_char: - case Type::unsigned_int: - case Type::unsigned_char: - case Type::imaginary_float: - case Type::packed_decimal: - case Type::numeric_string: - case Type::edited_string: - case Type::signed_fixed: - case Type::unsigned_fixed: - case Type::decimal_float: - if (tag != DW_TAG_base_type) - get_type_for_die = false; - else - { - if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding) - get_type_for_die = false; - } - break; - - case Type::indirect_const: get_type_for_die = tag == DW_TAG_const_type; break; - case Type::indirect_restrict: get_type_for_die = tag == DW_TAG_restrict_type; break; - case Type::indirect_volatile: get_type_for_die = tag == DW_TAG_volatile_type; break; - case Type::indirect_typedef: get_type_for_die = tag == DW_TAG_typedef; break; - case Type::indirect_pointer: get_type_for_die = tag == DW_TAG_pointer_type; break; - case Type::indirect_reference: get_type_for_die = tag == DW_TAG_reference_type; break; - - case Type::user_defined_type: - switch (tag) - { - case DW_TAG_array_type: - get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid); - break; - - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid); - break; - - case DW_TAG_enumeration_type: - get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid); - break; - - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: - get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid); - break; - } - } - } - } - - if (get_type_for_die) - { - TypeSP owning_type_sp; - TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0)); - - if (type_sp.get()) - { - // See if we are filtering results based on encoding? - bool add_type = (encoding == Type::invalid); - if (!add_type) - { - // We are filtering base on encoding, so lets check the resulting type encoding - add_type = (encoding == type_sp->GetEncoding()); - if (add_type) - { - // The type encoding matches, if this is a user defined type, lets - // make sure the exact user define type uid matches if one was provided - if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID) - { - UserDefType* udt = type_sp->GetUserDefinedType().get(); - if (udt) - add_type = udt->UserDefinedTypeUID() == udt_uid; - } - } - } - // Add the type to our list as long as everything matched - if (add_type) - { - types.InsertUnique(type_sp); - if (++num_matches >= max_matches) - break; - } - } + // We found a type pointer, now find the shared pointer form our type list + TypeSP type_sp (m_obj_file->GetModule()->GetTypeList()->FindType(matching_type->GetID())); + assert (type_sp.get() != NULL); + types.InsertUnique (type_sp); + ++num_matches; + if (num_matches >= max_matches) + break; } } // Return the number of variable that were appended to the list - return types.Size() - original_size; + return types.GetSize() - original_size; } -#endif - size_t SymbolFileDWARF::ParseChildParameters @@ -2692,6 +2590,30 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar break; } + if (type_name_cstr != NULL && sc.comp_unit != NULL && + (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus)) + { + static ConstString g_objc_type_name_id("id"); + static ConstString g_objc_type_name_Class("Class"); + static ConstString g_objc_type_name_selector("SEL"); + + if (type_name_dbstr == g_objc_type_name_id) + { + clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_id(); + ResolveTypeUID (encoding_uid); + } + else if (type_name_dbstr == g_objc_type_name_Class) + { + clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_Class(); + ResolveTypeUID (encoding_uid); + } + else if (type_name_dbstr == g_objc_type_name_selector) + { + clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_selector(); + ResolveTypeUID (encoding_uid); + } + } + type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type)); const_cast(die)->SetUserData(type_sp.get()); @@ -3024,7 +2946,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar if (func_type) return_clang_type = func_type->GetOpaqueClangQualType(); else - return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType(); + return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void(); std::vector function_param_types; std::vector function_param_decls; @@ -3165,7 +3087,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type); - size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8; + size_t byte_size = ClangASTType::GetClangTypeBitWidth (type_list->GetClangASTContext().getASTContext(), clang_type) / 8; type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type)); const_cast(die)->SetUserData(type_sp.get()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 7a9cd9cd42f1..a5364cd0aefa 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -101,7 +101,7 @@ public: virtual uint32_t FindGlobalVariables(const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables); virtual uint32_t FindFunctions(const lldb_private::ConstString &name, uint32_t name_type_mask, bool append, lldb_private::SymbolContextList& sc_list); virtual uint32_t FindFunctions(const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list); -// virtual uint32_t FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types); + virtual uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::TypeList& types); // virtual uint32_t FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types); @@ -164,7 +164,7 @@ public: // DWARFDebugPubnames* DebugPubBaseTypes(); // const DWARFDebugPubnames* DebugPubBaseTypes() const; // -// DWARFDebugPubnames* DebugPubtypes(); + DWARFDebugPubnames* DebugPubtypes(); // const DWARFDebugPubnames* DebugPubtypes() const; DWARFDebugRanges* DebugRanges(); @@ -289,7 +289,7 @@ protected: lldb_private::Type* GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, lldb::TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe); lldb::TypeSP GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, lldb::TypeSP& owning_type_sp, int32_t child_type, uint32_t idx); -// uint32_t FindTypes(std::vector die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types); + uint32_t FindTypes(std::vector die_offsets, uint32_t max_matches, lldb_private::TypeList& types); void Index(); @@ -323,7 +323,7 @@ protected: // std::auto_ptr m_pubnames; // std::auto_ptr m_pubbasetypes; // Just like m_pubtypes, but for DW_TAG_base_type DIEs -// std::auto_ptr m_pubtypes; + std::auto_ptr m_pubtypes; std::auto_ptr m_ranges; typedef llvm::DenseMap DIEToDeclContextMap; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index e760329034d4..0507437c8a17 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -810,16 +810,18 @@ SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool app return 0; } -// -//uint32_t -//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) -//{ -// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); -// if (oso_dwarf) -// return oso_dwarf->FindTypes (sc, name, append, max_matches, encoding, udt_uid, types); -// return 0; -//} -// + +uint32_t +SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) +{ + SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); + if (oso_dwarf) + return oso_dwarf->FindTypes (sc, name, append, max_matches, types); + if (!append) + types.Clear(); + return 0; +} + // //uint32_t //SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index d5e2b51e93cc..a14943f74df6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -66,7 +66,7 @@ public: virtual uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables); virtual uint32_t FindFunctions (const lldb_private::ConstString &name, uint32_t name_type_mask, bool append, lldb_private::SymbolContextList& sc_list); virtual uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list); -// virtual uint32_t FindTypes (const lldb_private::SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types); + virtual uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::TypeList& types); // virtual uint32_t FindTypes (const lldb_private::SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types); //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index a6d58f605556..e7af0bdfa8b9 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -346,14 +346,17 @@ SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool append, Sym return 0; } -//uint32_t -//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) -//{ -// return 0; -//} +uint32_t +SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::TypeList& types) +{ + if (!append) + types.Clear(); + + return 0; +} // //uint32_t -//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) +//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) //{ // return 0; //} diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index e3eeb29bb70c..da43985d31cc 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -92,11 +92,11 @@ public: virtual uint32_t FindFunctions(const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list); -// virtual uint32_t -// FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types); + virtual uint32_t + FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::TypeList& types); // virtual uint32_t -// FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types); +// FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::TypeList& types); //------------------------------------------------------------------ // PluginInterface protocol diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 10c5a2e4ada0..140ecba36b66 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -657,11 +657,29 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name } void * -ClangASTContext::GetVoidBuiltInType() +ClangASTContext::GetBuiltInType_void() { return getASTContext()->VoidTy.getAsOpaquePtr(); } +void * +ClangASTContext::GetBuiltInType_objc_id() +{ + return getASTContext()->getObjCIdType().getAsOpaquePtr(); +} + +void * +ClangASTContext::GetBuiltInType_objc_Class() +{ + return getASTContext()->getObjCClassType().getAsOpaquePtr(); +} + +void * +ClangASTContext::GetBuiltInType_objc_selector() +{ + return getASTContext()->getObjCSelType().getAsOpaquePtr(); +} + void * ClangASTContext::GetCStringType (bool is_const) { @@ -1176,7 +1194,6 @@ ClangASTContext::IsAggregateType (void *clang_type) case clang::Type::Record: case clang::Type::ObjCObject: case clang::Type::ObjCInterface: - case clang::Type::ObjCObjectPointer: return true; case clang::Type::Typedef: @@ -1200,6 +1217,19 @@ ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_cla const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { + case clang::Type::Builtin: + switch (cast(qual_type)->getKind()) + { + case clang::BuiltinType::ObjCId: // Child is Class + case clang::BuiltinType::ObjCClass: // child is Class + case clang::BuiltinType::ObjCSel: // child is const char * + num_children = 1; + + default: + break; + } + break; + case clang::Type::Record: { const RecordType *record_type = cast(qual_type.getTypePtr()); @@ -1272,8 +1302,18 @@ ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_cla break; case clang::Type::ObjCObjectPointer: - return ClangASTContext::GetNumChildren (cast(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), - omit_empty_base_classes); + { + ObjCObjectPointerType *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); + // If this type points to a simple type, then it has 1 child + if (num_pointee_children == 0) + num_children = 1; + else + num_children = num_pointee_children; + } + break; case clang::Type::ConstantArray: num_children = cast(qual_type.getTypePtr())->getSize().getLimitedValue(); @@ -1362,6 +1402,27 @@ ClangASTContext::GetChildClangTypeAtIndex QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); switch (parent_qual_type->getTypeClass()) { + case clang::Type::Builtin: + switch (cast(parent_qual_type)->getKind()) + { + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr(); + + case clang::BuiltinType::ObjCSel: + { + QualType char_type(ast_context->CharTy); + char_type.addConst(); + return ast_context->getPointerType(char_type).getAsOpaquePtr(); + } + break; + + default: + break; + } + break; + + case clang::Type::Record: { const RecordType *record_type = cast(parent_qual_type.getTypePtr()); @@ -1468,7 +1529,7 @@ ClangASTContext::GetChildClangTypeAtIndex { if (omit_empty_base_classes) { - if (ClangASTContext::GetNumChildren(superclass_interface_decl, omit_empty_base_classes) > 0) + if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) { if (idx == 0) { @@ -1480,10 +1541,7 @@ ClangASTContext::GetChildClangTypeAtIndex 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; + child_byte_offset = 0; return ivar_qual_type.getAsOpaquePtr(); } @@ -1494,6 +1552,8 @@ ClangASTContext::GetChildClangTypeAtIndex else ++child_idx; } + + const uint32_t superclass_idx = child_idx; if (idx < (child_idx + class_interface_decl->ivar_size())) { @@ -1514,7 +1574,7 @@ ClangASTContext::GetChildClangTypeAtIndex 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); + bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); child_byte_offset = bit_offset / 8; return ivar_qual_type.getAsOpaquePtr(); @@ -1529,17 +1589,41 @@ ClangASTContext::GetChildClangTypeAtIndex 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); + ObjCObjectPointerType *pointer_type = cast(parent_qual_type.getTypePtr()); + QualType pointee_type = pointer_type->getPointeeType(); + + if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) + { + return GetChildClangTypeAtIndex (ast_context, + parent_name, + pointer_type->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); + } + else + { + if (parent_name) + { + child_name.assign(1, '*'); + child_name += parent_name; + } + + // We have a pointer to an simple type + if (idx == 0) + { + std::pair clang_type_info = ast_context->getTypeInfo(pointee_type); + assert(clang_type_info.first % 8 == 0); + child_byte_size = clang_type_info.first / 8; + child_byte_offset = 0; + return pointee_type.getAsOpaquePtr(); + } + } } break; @@ -2688,22 +2772,6 @@ ClangASTContext::IsPointerOrReferenceType (void *clang_type, void **target_type) return false; } -size_t -ClangASTContext::GetTypeBitSize (clang::ASTContext *ast_context, void *clang_type) -{ - if (clang_type) - return ast_context->getTypeSize(QualType::getFromOpaquePtr(clang_type)); - return 0; -} - -size_t -ClangASTContext::GetTypeBitAlign (clang::ASTContext *ast_context, void *clang_type) -{ - if (clang_type) - return ast_context->getTypeAlign(QualType::getFromOpaquePtr(clang_type)); - return 0; -} - bool ClangASTContext::IsIntegerType (void *clang_type, bool &is_signed) { diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 615d7145e011..189ea335c169 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -13,6 +13,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/RecordLayout.h" @@ -230,7 +231,13 @@ ClangASTType::GetFormat (void *opaque_clang_qual_type) case clang::BuiltinType::Float: return lldb::eFormatFloat; case clang::BuiltinType::Double: return lldb::eFormatFloat; case clang::BuiltinType::LongDouble: return lldb::eFormatFloat; - case clang::BuiltinType::NullPtr: return lldb::eFormatHex; + case clang::BuiltinType::NullPtr: + case clang::BuiltinType::Overload: + case clang::BuiltinType::Dependent: + case clang::BuiltinType::UndeducedAuto: + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCSel: return lldb::eFormatHex; } break; case clang::Type::ObjCObjectPointer: return lldb::eFormatHex; @@ -750,6 +757,108 @@ ClangASTType::DumpSummary } } +uint64_t +ClangASTType::GetClangTypeBitWidth () +{ + return GetClangTypeBitWidth (m_ast, m_type); +} + +uint64_t +ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, void *opaque_clang_qual_type) +{ + if (ast_context && opaque_clang_qual_type) + return ast_context->getTypeSize(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); + return 0; +} + +size_t +ClangASTType::GetTypeBitAlign () +{ + return GetTypeBitAlign (m_ast, m_type); +} + +size_t +ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, void *opaque_clang_qual_type) +{ + if (ast_context && opaque_clang_qual_type) + return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); + return 0; +} + +void +ClangASTType::DumpTypeDescription (Stream *s) +{ + return DumpTypeDescription (m_ast, m_type, s); +} + +// Dump the full description of a type. For classes this means all of the +// ivars and member functions, for structs/unions all of the members. +void +ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, void *opaque_clang_qual_type, Stream *s) +{ + if (opaque_clang_qual_type) + { + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); + + llvm::SmallVector buf; + llvm::raw_svector_ostream llvm_ostrm (buf); + + clang::TagType *tag_type = dyn_cast(qual_type.getTypePtr()); + if (tag_type) + { + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + tag_decl->print(llvm_ostrm, 0); + } + else + { + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + clang::ObjCObjectType *objc_class_type = dyn_cast(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + if (class_interface_decl) + class_interface_decl->print(llvm_ostrm, ast_context->PrintingPolicy, s->GetIndentLevel()); + } + } + break; + + case clang::Type::Typedef: + { + const clang::TypedefType *typedef_type = qual_type->getAs(); + if (typedef_type) + { + const clang::TypedefDecl *typedef_decl = typedef_type->getDecl(); + std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString()); + if (!clang_typedef_name.empty()) + s->PutCString (clang_typedef_name.c_str()); + } + } + break; + + default: + { + std::string clang_type_name(qual_type.getAsString()); + if (!clang_type_name.empty()) + s->PutCString (clang_type_name.c_str()); + } + } + } + + llvm_ostrm.flush(); + if (buf.size() > 0) + { + s->Write (buf.data(), buf.size()); + } + } +} + bool ClangASTType::GetValueAsScalar ( diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index 94eec1e74783..45708330d71c 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -346,7 +346,7 @@ Function::GetReturnType () CalculateSymbolContext (&sc); // Null out everything below the CompUnit 'cause we don't actually know these. - size_t bit_size = ClangASTContext::GetTypeBitSize ((GetType()->GetClangASTContext().getASTContext()), &fun_return_qualtype); + size_t bit_size = ClangASTType::GetClangTypeBitWidth ((GetType()->GetClangASTContext().getASTContext()), fun_return_qualtype.getAsOpaquePtr()); Type return_type (0, GetType()->GetSymbolFile(), fun_return_name, bit_size, sc.comp_unit, 0, Type::eTypeUIDSynthetic, Declaration(), fun_return_qualtype.getAsOpaquePtr()); return return_type; } @@ -387,7 +387,7 @@ Function::GetArgumentTypeAtIndex (size_t idx) CalculateSymbolContext (&sc); // Null out everything below the CompUnit 'cause we don't actually know these. - size_t bit_size = ClangASTContext::GetTypeBitSize ((GetType()->GetClangASTContext().getASTContext()), &arg_qualtype); + size_t bit_size = ClangASTType::GetClangTypeBitWidth ((GetType()->GetClangASTContext().getASTContext()), arg_qualtype.getAsOpaquePtr()); Type arg_type (0, GetType()->GetSymbolFile(), arg_return_name, bit_size, sc.comp_unit, 0, Type::eTypeUIDSynthetic, Declaration(), arg_qualtype.getAsOpaquePtr()); return arg_type; } diff --git a/lldb/source/Symbol/SymbolVendor.cpp b/lldb/source/Symbol/SymbolVendor.cpp index b4c4f83e56b2..3d99ec543758 100644 --- a/lldb/source/Symbol/SymbolVendor.cpp +++ b/lldb/source/Symbol/SymbolVendor.cpp @@ -252,21 +252,16 @@ SymbolVendor::FindFunctions(const RegularExpression& regex, bool append, SymbolC } - -//uint32_t -//SymbolVendor::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) -//{ -// Mutex::Locker locker(m_mutex); -// if (m_sym_file_ap.get()) -// { -// lldb::user_id_t udt_uid = LLDB_INVALID_UID; -// if (encoding == Type::user_defined_type) -// udt_uid = UserDefType::GetUserDefTypeUID(udt_name); -// -// return m_sym_file_ap->FindTypes(sc, name, append, max_matches, encoding, udt_uid, types); -// } -// return 0; -//} +uint32_t +SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) +{ + Mutex::Locker locker(m_mutex); + if (m_sym_file_ap.get()) + return m_sym_file_ap->FindTypes(sc, name, append, max_matches, types); + if (!append) + types.Clear(); + return 0; +} // //uint32_t //SymbolVendor::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types) diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 845671ca2662..cd77e7ddd809 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -8,21 +8,6 @@ //===----------------------------------------------------------------------===// // Other libraries and framework includes -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclGroup.h" -#include "clang/AST/RecordLayout.h" - -#include "clang/Basic/Builtins.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" - -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/raw_ostream.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/DataBufferHeap.h" @@ -113,50 +98,15 @@ lldb_private::Type::GetDescription (Stream *s, lldb::DescriptionLevel level, boo m_decl.Dump(s); - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(m_clang_qual_type)); - - if (qual_type.getTypePtr()) + if (m_clang_qual_type) { - *s << ", type = "; + *s << ", clang_type = " << m_clang_qual_type << ' '; - clang::TagType *tag_type = dyn_cast(qual_type.getTypePtr()); - clang::TagDecl *tag_decl = NULL; - if (tag_type) - tag_decl = tag_type->getDecl(); - - if (tag_decl) - { - s->EOL(); - s->EOL(); - tag_decl->print(llvm::fouts(), 0); - s->EOL(); - } - else - { - const clang::TypedefType *typedef_type = qual_type->getAs(); - if (typedef_type) - { - 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(); - } - else - { - // We have a clang type, lets show it - clang::ASTContext *ast_context = GetClangAST(); - if (ast_context) - { - std::string clang_type_name(qual_type.getAsString()); - if (!clang_type_name.empty()) - *s << ' ' << clang_type_name.c_str(); - } - } - } + ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_qual_type, s); } else if (m_encoding_uid != LLDB_INVALID_UID) { - *s << ", type_uid = " << m_encoding_uid; + s->Printf(", type_uid = 0x%8.8x", m_encoding_uid); switch (m_encoding_uid_type) { case eIsTypeWithUID: s->PutCString(" (unresolved type)"); break; @@ -193,46 +143,11 @@ lldb_private::Type::Dump (Stream *s, bool show_context) m_decl.Dump(s); - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(m_clang_qual_type)); - - if (qual_type.getTypePtr()) + if (m_clang_qual_type) { - *s << ", clang_type = "; + *s << ", clang_type = " << m_clang_qual_type << ' '; - clang::TagType *tag_type = dyn_cast(qual_type.getTypePtr()); - clang::TagDecl *tag_decl = NULL; - if (tag_type) - tag_decl = tag_type->getDecl(); - - if (tag_decl) - { - s->EOL(); - s->EOL(); - tag_decl->print(llvm::fouts(), 0); - s->EOL(); - } - else - { - const clang::TypedefType *typedef_type = qual_type->getAs(); - if (typedef_type) - { - 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() << ')'; - } - else - { - // We have a clang type, lets show it - clang::ASTContext *ast_context = GetClangAST(); - if (ast_context) - { - std::string clang_type_name(qual_type.getAsString()); - if (!clang_type_name.empty()) - *s << '(' << clang_type_name.c_str() << ')'; - } - } - } + ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_qual_type, s); } else if (m_encoding_uid != LLDB_INVALID_UID) { @@ -303,19 +218,19 @@ lldb_private::Type::DumpValue } lldb_private::ClangASTType::DumpValue (GetClangAST (), - m_clang_qual_type, - exe_ctx, - s, - format == lldb::eFormatDefault ? GetFormat() : format, - data, - data_byte_offset, - GetByteSize(), - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, - show_summary, - verbose, - 0); + m_clang_qual_type, + exe_ctx, + s, + format == lldb::eFormatDefault ? GetFormat() : format, + data, + data_byte_offset, + GetByteSize(), + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, + show_summary, + verbose, + 0); } } @@ -339,7 +254,7 @@ lldb_private::Type::GetByteSize() } if (m_byte_size == 0) { - uint64_t bit_width = GetClangAST()->getTypeSize(clang::QualType::getFromOpaquePtr(GetOpaqueClangQualType())); + uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetOpaqueClangQualType()); m_byte_size = (bit_width + 7 ) / 8; } break; @@ -478,10 +393,8 @@ lldb_private::Type::GetTypeList() bool lldb_private::Type::ResolveClangType() { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(m_clang_qual_type)); - if (qual_type.getTypePtr() == NULL) + if (m_clang_qual_type == NULL) { - clang::QualType resolved_qual_type; TypeList *type_list = GetTypeList(); if (m_encoding_uid != LLDB_INVALID_UID) { @@ -492,38 +405,38 @@ lldb_private::Type::ResolveClangType() switch (m_encoding_uid_type) { case eIsTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(encoding_type->GetOpaqueClangQualType()); + m_clang_qual_type = encoding_type->GetOpaqueClangQualType(); break; case eIsConstTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(ClangASTContext::AddConstModifier (encoding_type->GetOpaqueClangQualType())); + m_clang_qual_type = ClangASTContext::AddConstModifier (encoding_type->GetOpaqueClangQualType()); break; case eIsRestrictTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(ClangASTContext::AddRestrictModifier (encoding_type->GetOpaqueClangQualType())); + m_clang_qual_type = ClangASTContext::AddRestrictModifier (encoding_type->GetOpaqueClangQualType()); break; case eIsVolatileTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(ClangASTContext::AddVolatileModifier (encoding_type->GetOpaqueClangQualType())); + m_clang_qual_type = ClangASTContext::AddVolatileModifier (encoding_type->GetOpaqueClangQualType()); break; case eTypedefToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->CreateClangTypedefType (this, encoding_type)); + m_clang_qual_type = type_list->CreateClangTypedefType (this, encoding_type); // Clear the name so it can get fully qualified in case the // typedef is in a namespace. m_name.Clear(); break; case ePointerToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->CreateClangPointerType (encoding_type)); + m_clang_qual_type = type_list->CreateClangPointerType (encoding_type); break; case eLValueReferenceToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->CreateClangLValueReferenceType (encoding_type)); + m_clang_qual_type = type_list->CreateClangLValueReferenceType (encoding_type); break; case eRValueReferenceToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->CreateClangRValueReferenceType (encoding_type)); + m_clang_qual_type = type_list->CreateClangRValueReferenceType (encoding_type); break; default: @@ -535,39 +448,39 @@ lldb_private::Type::ResolveClangType() else { // We have no encoding type, return void? - void *void_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType(); + void *void_clang_type = type_list->GetClangASTContext().GetBuiltInType_void(); switch (m_encoding_uid_type) { case eIsTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(void_clang_type); + m_clang_qual_type = void_clang_type; break; case eIsConstTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr (ClangASTContext::AddConstModifier (void_clang_type)); + m_clang_qual_type = ClangASTContext::AddConstModifier (void_clang_type); break; case eIsRestrictTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr (ClangASTContext::AddRestrictModifier (void_clang_type)); + m_clang_qual_type = ClangASTContext::AddRestrictModifier (void_clang_type); break; case eIsVolatileTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr (ClangASTContext::AddVolatileModifier (void_clang_type)); + m_clang_qual_type = ClangASTContext::AddVolatileModifier (void_clang_type); break; case eTypedefToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL)); + m_clang_qual_type = type_list->GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL); break; case ePointerToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->GetClangASTContext().CreatePointerType (void_clang_type)); + m_clang_qual_type = type_list->GetClangASTContext().CreatePointerType (void_clang_type); break; case eLValueReferenceToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->GetClangASTContext().CreateLValueReferenceType (void_clang_type)); + m_clang_qual_type = type_list->GetClangASTContext().CreateLValueReferenceType (void_clang_type); break; case eRValueReferenceToTypeWithUID: - resolved_qual_type = clang::QualType::getFromOpaquePtr(type_list->GetClangASTContext().CreateRValueReferenceType (void_clang_type)); + m_clang_qual_type = type_list->GetClangASTContext().CreateRValueReferenceType (void_clang_type); break; default: @@ -575,11 +488,6 @@ lldb_private::Type::ResolveClangType() break; } } - if (resolved_qual_type.getTypePtr()) - { - m_clang_qual_type = resolved_qual_type.getAsOpaquePtr(); - } - } return m_clang_qual_type != NULL; } diff --git a/lldb/test/foundation/main.m b/lldb/test/foundation/main.m index d45fb4e14f2b..ade204e5a8a9 100644 --- a/lldb/test/foundation/main.m +++ b/lldb/test/foundation/main.m @@ -3,7 +3,13 @@ int main (int argc, char const *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSString *str = [NSString stringWithFormat:@"Hello from '%s'", argv[0]]; + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", argv[0]]; + id str_id = str; + SEL sel = @selector(length); + BOOL responds = [str respondsToSelector:sel]; + printf("sizeof(id) = %zu\n", sizeof(id)); + printf("sizeof(Class) = %zu\n", sizeof(Class)); + printf("sizeof(SEL) = %zu\n", sizeof(SEL)); [pool release]; return 0; }