Added support for persistent types to the
expression parser.  You can use a persistent
type like this:

(lldb) expr struct $foo { int a; int b; };
(lldb) struct $foo i; i.a = 2; i.b = 3; i
($foo) $0 = {
  (int) a = 2
  (int) b = 3
}

typedefs work similarly.

This patch affects the following files:

test/expression_command/persistent_types/*
  A test case for persistent types,
  in particular structs and typedefs.

ClangForward.h
  Added TypeDecl, needed to declare some
  functions in ASTResultSynthesizer.h

ClangPersistentVariables.[h,cpp]
  Added a list of persistent types to the
  persistent variable store.

ASTResultSynthesizer.[h,cpp]
  Made the AST result synthesizer iterate
  across TypeDecls in the expression, and
  record any persistent types found.  Also
  made a minor documentation fix.

ClangUserExpression.[h,cpp]
  Extended the user expression class to
  keep the state needed to report the
  persistent variable store for the target
  to the AST result synthesizers. 

  Also introduced a new error code for
  expressions that executed normally but
  did not return a result.

CommandObjectExpression.cpp
  Improved output for expressions (like 
  declarations of new persistent types) that
  don't return a result.  This is no longer
  treated as an error.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@138383 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index ca5ca15..694c904 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -347,24 +347,34 @@
             }
             else
             {
-                const char *error_cstr = result_valobj_sp->GetError().AsCString();
-                if (error_cstr && error_cstr[0])
+                if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
                 {
-                    int error_cstr_len = strlen (error_cstr);
-                    const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
-                    if (strstr(error_cstr, "error:") != error_cstr)
-                        error_stream->PutCString ("error: ");
-                    error_stream->Write(error_cstr, error_cstr_len);
-                    if (!ends_with_newline)
-                        error_stream->EOL();
+                    error_stream->PutCString("<no result>\n");
+                    
+                    if (result)
+                        result->SetStatus (eReturnStatusSuccessFinishResult);
                 }
                 else
                 {
-                    error_stream->PutCString ("error: unknown error\n");
+                    const char *error_cstr = result_valobj_sp->GetError().AsCString();
+                    if (error_cstr && error_cstr[0])
+                    {
+                        int error_cstr_len = strlen (error_cstr);
+                        const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
+                        if (strstr(error_cstr, "error:") != error_cstr)
+                            error_stream->PutCString ("error: ");
+                        error_stream->Write(error_cstr, error_cstr_len);
+                        if (!ends_with_newline)
+                            error_stream->EOL();
+                    }
+                    else
+                    {
+                        error_stream->PutCString ("error: unknown error\n");
+                    }
+                    
+                    if (result)
+                        result->SetStatus (eReturnStatusFailed);
                 }
-
-                if (result)
-                    result->SetStatus (eReturnStatusFailed);
             }
         }
     }