Fixed the "expression" command object to use the StackFrame::GetValueForExpressionPath()
function and also hooked up better error reporting for when things fail.

Fixed issues with trying to display children of pointers when none are
supposed to be shown (no children for function pointers, and more like this).
This was causing child value objects to be made that were correctly firing
an assertion.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@121841 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index cd725ca..05643e63 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -1901,7 +1901,10 @@
             break;
         }
         break;
-        
+
+    case clang::Type::Complex:
+        return 2;
+
     case clang::Type::Record:
         if (ClangASTType::IsDefined (clang_qual_type))
         {
@@ -1995,12 +1998,15 @@
     case clang::Type::Pointer:
         {
             PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
-            QualType pointee_type = pointer_type->getPointeeType();
+            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;
+            {
+                // We have a pointer to a pointee type that claims it has no children.
+                // We will want to look at
+                num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
+            }
             else
                 num_children = num_pointee_children;
         }
@@ -2032,6 +2038,60 @@
     return num_children;
 }
 
+// If a pointer to a pointee type (the clang_type arg) says that it has no 
+// children, then we either need to trust it, or override it and return a 
+// different result. For example, an "int *" has one child that is an integer, 
+// but a function pointer doesn't have any children. Likewise if a Record type
+// claims it has no children, then there really is nothing to show.
+uint32_t
+ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return 0;
+
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::Builtin:                  return 1;
+    case clang::Type::Complex:                  return 2;
+    case clang::Type::Pointer:                  return 1;
+    case clang::Type::BlockPointer:             return 0;   // If block pointers don't have debug info, then no children for them
+    case clang::Type::LValueReference:          return 1;
+    case clang::Type::RValueReference:          return 1;
+    case clang::Type::MemberPointer:            return 0;
+    case clang::Type::ConstantArray:            return 0;
+    case clang::Type::IncompleteArray:          return 0;
+    case clang::Type::VariableArray:            return 0;
+    case clang::Type::DependentSizedArray:      return 0;
+    case clang::Type::DependentSizedExtVector:  return 0;
+    case clang::Type::Vector:                   return 0;
+    case clang::Type::ExtVector:                return 0;
+    case clang::Type::FunctionProto:            return 0;   // When we function pointers, they have no children...
+    case clang::Type::FunctionNoProto:          return 0;   // When we function pointers, they have no children...
+    case clang::Type::UnresolvedUsing:          return 0;
+    case clang::Type::Paren:                    return 0;
+    case clang::Type::Typedef:                  return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+    case clang::Type::TypeOfExpr:               return 0;
+    case clang::Type::TypeOf:                   return 0;
+    case clang::Type::Decltype:                 return 0;
+    case clang::Type::Record:                   return 0;
+    case clang::Type::Enum:                     return 1;
+    case clang::Type::Elaborated:               return 1;
+    case clang::Type::TemplateTypeParm:         return 1;
+    case clang::Type::SubstTemplateTypeParm:    return 1;
+    case clang::Type::TemplateSpecialization:   return 1;
+    case clang::Type::InjectedClassName:        return 0;
+    case clang::Type::DependentName:            return 1;
+    case clang::Type::DependentTemplateSpecialization:  return 1;
+    case clang::Type::ObjCObject:               return 0;
+    case clang::Type::ObjCInterface:            return 0;
+    case clang::Type::ObjCObjectPointer:        return 1;
+    default: 
+        break;
+    }
+    return 0;
+}
 
 clang_type_t
 ClangASTContext::GetChildClangTypeAtIndex