summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/Block.h3
-rw-r--r--lldb/include/lldb/Symbol/Function.h10
-rw-r--r--lldb/include/lldb/Symbol/SymbolFile.h3
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp7
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp59
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp87
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h13
-rw-r--r--lldb/source/Symbol/Block.cpp24
-rw-r--r--lldb/source/Symbol/Function.cpp24
-rw-r--r--lldb/source/Symbol/Type.cpp2
-rw-r--r--lldb/test/lang/cpp/this/Makefile5
-rw-r--r--lldb/test/lang/cpp/this/TestCPPThis.py67
-rw-r--r--lldb/test/lang/cpp/this/main.cpp53
-rw-r--r--lldb/test/lang/objc/self/Makefile6
-rw-r--r--lldb/test/lang/objc/self/TestObjCSelf.py55
-rw-r--r--lldb/test/lang/objc/self/main.m52
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
OpenPOWER on IntegriCloud