lldb-59.
llvm-svn: 132304
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 7759164..cf55db8 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -87,11 +87,14 @@
if (tag_decl->hasExternalLexicalStorage())
{
- ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
+ if (ast)
{
- external_ast_source->CompleteType(tag_decl);
- return !tag_type->isIncompleteType();
+ ExternalASTSource *external_ast_source = ast->getExternalSource();
+ if (external_ast_source)
+ {
+ external_ast_source->CompleteType(tag_decl);
+ return !tag_type->isIncompleteType();
+ }
}
}
return false;
@@ -113,11 +116,14 @@
bool is_forward_decl = class_interface_decl->isForwardDecl();
if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
{
- ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
+ if (ast)
{
- external_ast_source->CompleteType (class_interface_decl);
- is_forward_decl = class_interface_decl->isForwardDecl();
+ ExternalASTSource *external_ast_source = ast->getExternalSource();
+ if (external_ast_source)
+ {
+ external_ast_source->CompleteType (class_interface_decl);
+ is_forward_decl = class_interface_decl->isForwardDecl();
+ }
}
return is_forward_decl == false;
}
@@ -3980,6 +3986,121 @@
}
bool
+ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
+{
+ QualType pointee_qual_type;
+ if (clang_type)
+ {
+ QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ bool success = false;
+ switch (type_class)
+ {
+ case clang::Type::Pointer:
+ pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::Typedef:
+ return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
+
+ default:
+ break;
+ }
+
+ if (success)
+ {
+ // Check to make sure what we are pointing too is a possible dynamic C++ type
+ // We currently accept any "void *" (in case we have a class that has been
+ // watered down to an opaque pointer) and virtual C++ classes.
+ const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
+ switch (pointee_type_class)
+ {
+ case clang::Type::Builtin:
+ switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
+ {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+ return true;
+
+ case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::BoundMember:
+ break;
+ }
+ break;
+ case clang::Type::Record:
+ {
+ CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (GetCompleteQualType (ast, pointee_qual_type))
+ {
+ success = cxx_record_decl->isPolymorphic() || cxx_record_decl->isAbstract();
+ }
+ else
+ {
+ // We failed to get the complete type, so we have to
+ // treat this as a void * which we might possibly be
+ // able to complete
+ success = true;
+ }
+ if (success)
+ {
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+ return true;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (dynamic_pointee_type)
+ *dynamic_pointee_type = NULL;
+ return false;
+}
+
+
+bool
ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
{
if (clang_type == NULL)
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index f264e14..7f841b4 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -156,40 +156,53 @@
sc->Clear();
}
+bool
+Variable::LocationIsValidForFrame (StackFrame *frame)
+{
+ // Is the variable is described by a single location?
+ if (!m_location.IsLocationList())
+ {
+ // Yes it is, the location is valid.
+ return true;
+ }
+
+ if (frame)
+ {
+ Target *target = &frame->GetThread().GetProcess().GetTarget();
+
+ Function *function = frame->GetSymbolContext(eSymbolContextFunction).function;
+ if (function)
+ {
+ addr_t loclist_base_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
+ if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
+ return false;
+ // It is a location list. We just need to tell if the location
+ // list contains the current address when converted to a load
+ // address
+ return m_location.LocationListContainsAddress (loclist_base_load_addr,
+ frame->GetFrameCodeAddress().GetLoadAddress (target));
+ }
+ }
+ return false;
+}
bool
Variable::IsInScope (StackFrame *frame)
{
switch (m_scope)
{
- case eValueTypeVariableGlobal:
- case eValueTypeVariableStatic:
- // Globals and statics are always in scope.
+ case eValueTypeRegister:
+ case eValueTypeRegisterSet:
+ return frame != NULL;
+
+ case eValueTypeConstResult:
return true;
+ case eValueTypeVariableGlobal:
+ case eValueTypeVariableStatic:
case eValueTypeVariableArgument:
case eValueTypeVariableLocal:
- // Check if the location has a location list that describes the value
- // of the variable with address ranges and different locations for each
- // address range?
- if (m_location.IsLocationList())
- {
- SymbolContext sc;
- CalculateSymbolContext(&sc);
-
- // Currently we only support functions that have things with
- // locations lists. If this expands, we will need to add support
- assert (sc.function);
- Target *target = &frame->GetThread().GetProcess().GetTarget();
- addr_t loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
- if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
- return false;
- // It is a location list. We just need to tell if the location
- // list contains the current address when converted to a load
- // address
- return m_location.LocationListContainsAddress (loclist_base_load_addr, frame->GetFrameCodeAddress().GetLoadAddress (target));
- }
- else
+ if (frame)
{
// We don't have a location list, we just need to see if the block
// that this variable was defined in is currently
@@ -198,16 +211,19 @@
{
SymbolContext variable_sc;
CalculateSymbolContext (&variable_sc);
+ // Check for static or global variable defined at the compile unit
+ // level that wasn't defined in a block
+ if (variable_sc.block == NULL)
+ return true;
+
if (variable_sc.block == deepest_frame_block)
return true;
-
return variable_sc.block->Contains (deepest_frame_block);
}
}
break;
default:
- assert (!"Unhandled case");
break;
}
return false;