diff options
| -rw-r--r-- | lldb/include/lldb/Symbol/Block.h | 3 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/Function.h | 10 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/SymbolFile.h | 3 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 7 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 59 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 87 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 13 | ||||
| -rw-r--r-- | lldb/source/Symbol/Block.cpp | 24 | ||||
| -rw-r--r-- | lldb/source/Symbol/Function.cpp | 24 | ||||
| -rw-r--r-- | lldb/source/Symbol/Type.cpp | 2 | ||||
| -rw-r--r-- | lldb/test/lang/cpp/this/Makefile | 5 | ||||
| -rw-r--r-- | lldb/test/lang/cpp/this/TestCPPThis.py | 67 | ||||
| -rw-r--r-- | lldb/test/lang/cpp/this/main.cpp | 53 | ||||
| -rw-r--r-- | lldb/test/lang/objc/self/Makefile | 6 | ||||
| -rw-r--r-- | lldb/test/lang/objc/self/TestObjCSelf.py | 55 | ||||
| -rw-r--r-- | lldb/test/lang/objc/self/main.m | 52 |
16 files changed, 418 insertions, 52 deletions
diff --git a/lldb/include/lldb/Symbol/Block.h b/lldb/include/lldb/Symbol/Block.h index 765c845f9a0..3681749b762 100644 --- a/lldb/include/lldb/Symbol/Block.h +++ b/lldb/include/lldb/Symbol/Block.h @@ -336,6 +336,9 @@ public: { return m_inlineInfoSP.get(); } + + clang::DeclContext * + GetClangDeclContextForInlinedFunction(); //------------------------------------------------------------------ /// Get the memory cost of this object. diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h index 3ffa23030e9..27850d174f1 100644 --- a/lldb/include/lldb/Symbol/Function.h +++ b/lldb/include/lldb/Symbol/Function.h @@ -10,6 +10,7 @@ #ifndef liblldb_Function_h_ #define liblldb_Function_h_ +#include "lldb/Core/ClangForward.h" #include "lldb/Core/AddressRange.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Declaration.h" @@ -527,6 +528,15 @@ public: } //------------------------------------------------------------------ + /// Get the DeclContext for this function, if available. + /// + /// @return + /// The DeclContext, or NULL if none exists. + //------------------------------------------------------------------ + clang::DeclContext * + GetClangDeclContext(); + + //------------------------------------------------------------------ /// Get accessor for the type that describes the function /// return value type, and paramter types. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index f65eb9eae43..1e5dec80b55 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -113,7 +113,8 @@ public: virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0; virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0; virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) = 0; - virtual clang::DeclContext* GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) { return NULL; } + virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) { return NULL; } + virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) { return NULL; } virtual uint32_t ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0; virtual uint32_t ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) = 0; virtual uint32_t FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) = 0; diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index ebcaa013c42..f4598dd364a 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -1874,7 +1874,12 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &pointer_target_type)) return; - TypeFromUser class_user_type(pointer_target_type, + clang::QualType pointer_target_qual_type = QualType::getFromOpaquePtr(pointer_target_type); + + if (pointer_target_qual_type.isConstQualified()) + pointer_target_qual_type.removeLocalConst(); + + TypeFromUser class_user_type(pointer_target_qual_type.getAsOpaquePtr(), this_type->GetClangAST()); if (log) diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 71a528280d9..b4a704cf33c 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -37,6 +37,9 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallUserExpression.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" + using namespace lldb_private; ClangUserExpression::ClangUserExpression (const char *expr, @@ -68,44 +71,46 @@ ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx) { - VariableList *vars = exe_ctx.frame->GetVariableList(false); + if (!exe_ctx.frame) + return; + + SymbolContext sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextFunction); - if (!vars) + if (!sym_ctx.function) return; - lldb::VariableSP this_var(vars->FindVariable(ConstString("this"))); - lldb::VariableSP self_var(vars->FindVariable(ConstString("self"))); + clang::DeclContext *decl_context; - if (this_var.get()) - { - Type *this_type = this_var->GetType(); + if (sym_ctx.block && sym_ctx.block->GetInlinedFunctionInfo()) + decl_context = sym_ctx.block->GetClangDeclContextForInlinedFunction(); + else + decl_context = sym_ctx.function->GetClangDeclContext(); - lldb::clang_type_t pointer_target_type; + if (!decl_context) + return; - if (ClangASTContext::IsPointerType(this_type->GetClangForwardType(), - &pointer_target_type)) + if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context)) + { + if (method_decl->isInstance()) { - TypeFromUser target_ast_type(pointer_target_type, this_type->GetClangAST()); - - if (ClangASTContext::IsCXXClassType(target_ast_type.GetOpaqueQualType())) - { - m_cplusplus = true; + m_cplusplus = true; - if (target_ast_type.IsConst()) - m_const_object = true; - } + do { + clang::QualType this_type = method_decl->getThisType(decl_context->getParentASTContext()); + + const clang::PointerType *this_pointer_type = llvm::dyn_cast<clang::PointerType>(this_type.getTypePtr()); + + if (!this_pointer_type) + break; + + clang::QualType this_pointee_type = this_pointer_type->getPointeeType(); + } while (0); } } - else if (self_var.get()) + else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context)) { - m_objectivec = true; - - Type *self_type = self_var->GetType(); - - if (self_type->GetClangForwardType() == self_type->GetClangASTContext().GetBuiltInType_objc_id()) - { - m_objectivec = false; - } + if (method_decl->isInstanceMethod()) + m_objectivec = true; } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index c29a78db9b4..4cb3576a194 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1355,7 +1355,7 @@ SymbolFileDWARF::ParseChildMembers clang::DeclContext* -SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) +SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) { DWARFDebugInfo* debug_info = DebugInfo(); if (debug_info) @@ -1363,7 +1363,21 @@ SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) DWARFCompileUnitSP cu_sp; const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); if (die) - return GetClangDeclContextForDIE (cu_sp.get(), die); + return GetClangDeclContextContainingDIE (cu_sp.get(), die); + } + return NULL; +} + +clang::DeclContext* +SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) +{ + DWARFDebugInfo* debug_info = DebugInfo(); + if (debug_info) + { + DWARFCompileUnitSP cu_sp; + const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); + if (die) + return GetClangDeclContextForDIE (sc, cu_sp.get(), die); } return NULL; } @@ -2799,17 +2813,28 @@ SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoE } clang::DeclContext * -SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset) +SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset) { if (die_offset != DW_INVALID_OFFSET) { DWARFCompileUnitSP cu_sp; const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); - return GetClangDeclContextForDIE (cu_sp.get(), die); + return GetClangDeclContextContainingDIE (cu_sp.get(), die); } return NULL; } +clang::DeclContext * +SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset) +{ + if (die_offset != DW_INVALID_OFFSET) + { + DWARFCompileUnitSP cu_sp; + const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); + return GetClangDeclContextForDIE (sc, cu_sp.get(), die); + } + return NULL; +} clang::NamespaceDecl * SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) @@ -2820,7 +2845,7 @@ SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebu if (namespace_name) { Declaration decl; // TODO: fill in the decl object - clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent())); + clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent())); if (namespace_decl) LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); return namespace_decl; @@ -2830,12 +2855,36 @@ SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebu } clang::DeclContext * -SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) +SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) +{ + // If this DIE has a specification, or an abstract origin, then trace to those. + + dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) + return GetClangDeclContextForDIEOffset (sc, die_offset); + + die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); + if (die_offset != DW_INVALID_OFFSET) + return GetClangDeclContextForDIEOffset (sc, die_offset); + + // This is the DIE we want. Parse it, then query our map. + + ParseType(sc, curr_cu, die, NULL); + + DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); + if (pos != m_die_to_decl_ctx.end()) + return pos->second; + else + return NULL; +} + +clang::DeclContext * +SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) { if (m_clang_tu_decl == NULL) m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset()); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x )\n", die->GetOffset()); const DWARFDebugInfoEntry * const decl_die = die; clang::DeclContext *decl_ctx = NULL; @@ -2849,11 +2898,11 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); if (pos != m_die_to_decl_ctx.end()) { - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); return pos->second; } - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); switch (die->Tag()) { @@ -2863,10 +2912,10 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA if (namespace_name) { Declaration decl; // TODO: fill in the decl object - clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die)); + clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die)); if (namespace_decl) { - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); } return namespace_decl; @@ -2882,7 +2931,7 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA pos = m_die_to_decl_ctx.find(die); if (pos != m_die_to_decl_ctx.end()) { - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); return pos->second; } else @@ -2905,8 +2954,8 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); if (die_offset != DW_INVALID_OFFSET) { - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset); - decl_ctx = GetClangDeclContextForDIEOffset (die_offset); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset); + decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset); if (decl_ctx != m_clang_tu_decl) return decl_ctx; } @@ -2914,8 +2963,8 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); if (die_offset != DW_INVALID_OFFSET) { - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset); - decl_ctx = GetClangDeclContextForDIEOffset (die_offset); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset); + decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset); if (decl_ctx != m_clang_tu_decl) return decl_ctx; } @@ -2923,7 +2972,7 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA die = die->GetParent(); } // Right now we have only one translation unit per module... - //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset()); + //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset()); return m_clang_tu_decl; } @@ -3309,7 +3358,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, clang_type_was_created = true; clang_type = ast.CreateRecordType (type_name_cstr, tag_decl_kind, - GetClangDeclContextForDIE (dwarf_cu, die), + GetClangDeclContextContainingDIE (dwarf_cu, die), class_language); } @@ -3417,7 +3466,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, DW_ATE_signed, byte_size * 8); clang_type = ast.CreateEnumerationType (type_name_cstr, - GetClangDeclContextForDIE (dwarf_cu, die), + GetClangDeclContextContainingDIE (dwarf_cu, die), decl, enumerator_clang_type); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 56e7abed291..374092325b5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -101,7 +101,8 @@ public: virtual lldb::clang_type_t ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_opaque_type); virtual lldb_private::Type* ResolveType (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed = true); - virtual clang::DeclContext* GetClangDeclContextForTypeUID (lldb::user_id_t type_uid); + virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid); + virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid); virtual uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc); virtual uint32_t ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list); @@ -183,10 +184,16 @@ public: SupportedVersion(uint16_t version); clang::DeclContext * - GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die); + GetClangDeclContextForDIE (const lldb_private::SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die); + + clang::DeclContext * + GetClangDeclContextForDIEOffset (const lldb_private::SymbolContext &sc, dw_offset_t die_offset); + + clang::DeclContext * + GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die); clang::DeclContext * - GetClangDeclContextForDIEOffset (dw_offset_t die_offset); + GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset); void SearchDeclContext (const clang::DeclContext *decl_context, diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp index a7d5c5c6f87..8be43e7825d 100644 --- a/lldb/source/Symbol/Block.cpp +++ b/lldb/source/Symbol/Block.cpp @@ -11,6 +11,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/VariableList.h" @@ -535,6 +536,29 @@ Block::AppendVariables return num_variables_added; } +clang::DeclContext * +Block::GetClangDeclContextForInlinedFunction() +{ + SymbolContext sc; + + CalculateSymbolContext (&sc); + + if (!sc.module_sp) + return NULL; + + SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor(); + + if (!sym_vendor) + return NULL; + + SymbolFile *sym_file = sym_vendor->GetSymbolFile(); + + if (!sym_file) + return NULL; + + return sym_file->GetClangDeclContextForTypeUID (sc, m_uid); +} + void Block::SetBlockInfoHasBeenParsed (bool b, bool set_children) { diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index c2ef05d3251..5328159fdb7 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -14,6 +14,7 @@ #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" @@ -399,6 +400,29 @@ Function::MemorySize () const return mem_size; } +clang::DeclContext * +Function::GetClangDeclContext() +{ + SymbolContext sc; + + CalculateSymbolContext (&sc); + + if (!sc.module_sp) + return NULL; + + SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor(); + + if (!sym_vendor) + return NULL; + + SymbolFile *sym_file = sym_vendor->GetSymbolFile(); + + if (!sym_file) + return NULL; + + return sym_file->GetClangDeclContextForTypeUID (sc, m_uid); +} + Type* Function::GetType() { diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 67f2e80262b..46d8700db80 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -640,7 +640,7 @@ Type::CreateClangTypedefType (Type *typedef_type, Type *base_type) assert(typedef_type && base_type); return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), base_type->GetClangForwardType(), - typedef_type->GetSymbolFile()->GetClangDeclContextForTypeUID(typedef_type->GetID())); + typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID())); } void * diff --git a/lldb/test/lang/cpp/this/Makefile b/lldb/test/lang/cpp/this/Makefile new file mode 100644 index 00000000000..314f1cb2f07 --- /dev/null +++ b/lldb/test/lang/cpp/this/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/lang/cpp/this/TestCPPThis.py b/lldb/test/lang/cpp/this/TestCPPThis.py new file mode 100644 index 00000000000..3efb84d102b --- /dev/null +++ b/lldb/test/lang/cpp/this/TestCPPThis.py @@ -0,0 +1,67 @@ +""" +Tests that C++ member and static variables are available where they should be. +""" + +from lldbtest import * + +class CPPThisTestCase(TestBase): + + mydir = os.path.join("lang", "cpp", "this") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test that the appropriate member variables are available when stopped in C++ static, inline, and const methods""" + self.buildDsym() + self.static_method_commands() + + def test_with_dwarf_and_run_command(self): + """Test that the appropriate member variables are available when stopped in C++ static, inline, and const methods""" + self.buildDwarf() + self.static_method_commands() + + def setUp(self): + TestBase.setUp(self) + + def set_breakpoint(self, line): + self.expect("breakpoint set -f main.cpp -l %d" % line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created") + + def static_method_commands(self): + """Test that the appropriate member variables are available when stopped in C++ static, inline, and const methods""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.set_breakpoint(line_number('main.cpp', '// breakpoint 1')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 2')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 3')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 4')) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- m_a = 2", + startstr = "(int) $0 = 2") + + self.runCmd("process continue") + + # This would be disallowed if we enforced const. But we don't. + self.expect("expression -- m_a = 2", + startstr = "(int) $1 = 2") + + self.expect("expression -- m_a", + startstr = "(int) $2 = 2") + + self.runCmd("process continue") + + self.expect("expression -- s_a", + startstr = "(int) $3 = 5") + + self.runCmd("process continue") + + self.expect("expression -- m_a", + startstr = "(int) $4 = 2") + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/lang/cpp/this/main.cpp b/lldb/test/lang/cpp/this/main.cpp new file mode 100644 index 00000000000..80afce1c2da --- /dev/null +++ b/lldb/test/lang/cpp/this/main.cpp @@ -0,0 +1,53 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +class A +{ +public: + void accessMember(int a); + int accessMemberConst() const; + static int accessStaticMember(); + + int accessMemberInline(int a) __attribute__ ((always_inline)) + { + m_a = a; // breakpoint 4 + } + + int m_a; + static int s_a; +}; + +int A::s_a = 5; + +void A::accessMember(int a) +{ + m_a = a; // breakpoint 1 +} + +int A::accessMemberConst() const +{ + return m_a; // breakpoint 2 +} + +int A::accessStaticMember() +{ + return s_a; // breakpoint 3 +} + +int main() +{ + A my_a; + + my_a.accessMember(3); + my_a.accessMemberConst(); + A::accessStaticMember(); + my_a.accessMemberInline(5); +} diff --git a/lldb/test/lang/objc/self/Makefile b/lldb/test/lang/objc/self/Makefile new file mode 100644 index 00000000000..fc7449d908b --- /dev/null +++ b/lldb/test/lang/objc/self/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +OBJC_SOURCES := main.m +LDFLAGS := $(CFLAGS) -lobjc -framework Foundation + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/lang/objc/self/TestObjCSelf.py b/lldb/test/lang/objc/self/TestObjCSelf.py new file mode 100644 index 00000000000..c40cdb000bb --- /dev/null +++ b/lldb/test/lang/objc/self/TestObjCSelf.py @@ -0,0 +1,55 @@ +""" +Tests that ObjC member variables are available where they should be. +""" + +from lldbtest import * + +class ObjCSelfTestCase(TestBase): + + mydir = os.path.join("lang", "objc", "self") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test that the appropriate member variables are available when stopped in Objective-C class and instance methods""" + self.buildDsym() + self.self_commands() + + def test_with_dwarf_and_run_command(self): + """Test that the appropriate member variables are available when stopped in Objective-C class and instance methods""" + self.buildDwarf() + self.self_commands() + + def setUp(self): + TestBase.setUp(self) + + def set_breakpoint(self, line): + self.expect("breakpoint set -f main.m -l %d" % line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created") + + def self_commands(self): + """Test that the appropriate member variables are available when stopped in Objective-C class and instance methods""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.set_breakpoint(line_number('main.m', '// breakpoint 1')) + self.set_breakpoint(line_number('main.m', '// breakpoint 2')) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- m_a = 2", + startstr = "(int) $0 = 2") + + self.runCmd("process continue") + + # This would be disallowed if we enforced const. But we don't. + self.expect("expression -- m_a = 2", + error=True) + + self.expect("expression -- s_a", + startstr = "(int) $1 = 5") + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/lang/objc/self/main.m b/lldb/test/lang/objc/self/main.m new file mode 100644 index 00000000000..206bd76d631 --- /dev/null +++ b/lldb/test/lang/objc/self/main.m @@ -0,0 +1,52 @@ +//===-- main.m ------------------------------------------*- Objective-C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +@interface A : NSObject +{ + int m_a; +} +-(id)init; +-(void)accessMember:(int)a; ++(int)accessStaticMember:(int)a; +@end + +static int s_a = 5; + +@implementation A +-(id)init +{ + self = [super init]; + + if (self) + m_a = 2; +} + +-(void)accessMember:(int)a +{ + m_a = a; // breakpoint 1 +} + ++(int)accessStaticMember:(int)a +{ + s_a = a; // breakpoint 2 +} +@end + +int main() +{ + NSAutoreleasePool *pool = [NSAutoreleasePool alloc]; + A *my_a = [[A alloc] init]; + + [my_a accessMember:3]; + [A accessStaticMember:5]; + + [pool release]; +}
\ No newline at end of file |

