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.

llvm-svn: 138383
diff --git a/lldb/source/Expression/ASTResultSynthesizer.cpp b/lldb/source/Expression/ASTResultSynthesizer.cpp
index 1125d62..b2b593b 100644
--- a/lldb/source/Expression/ASTResultSynthesizer.cpp
+++ b/lldb/source/Expression/ASTResultSynthesizer.cpp
@@ -19,19 +19,25 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/raw_ostream.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/ASTResultSynthesizer.h"
+#include "lldb/Symbol/ClangASTContext.h"
 
 using namespace llvm;
 using namespace clang;
 using namespace lldb_private;
 
 ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
-                                           TypeFromUser desired_type) :
+                                           TypeFromUser desired_type,
+                                           ASTContext &scratch_ast_context,
+                                           ClangPersistentVariables &persistent_vars) :
     m_ast_context (NULL),
     m_passthrough (passthrough),
     m_passthrough_sema (NULL),
     m_sema (NULL),
-    m_desired_type (desired_type)
+    m_desired_type (desired_type),
+    m_scratch_ast_context (scratch_ast_context),
+    m_persistent_vars (persistent_vars)
 {
     if (!m_passthrough)
         return;
@@ -87,6 +93,7 @@
         if (m_ast_context &&
             !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
         {
+            RecordPersistentTypes(method_decl);
             SynthesizeObjCMethodResult(method_decl);
         }
     }
@@ -95,6 +102,7 @@
         if (m_ast_context &&
             !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
         {
+            RecordPersistentTypes(function_decl);
             SynthesizeFunctionResult(function_decl);
         }
     }
@@ -397,9 +405,51 @@
         m_passthrough->HandleTranslationUnit(Ctx);
 }
 
+void
+ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
+{
+    typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
+    
+    for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()), 
+         e = TypeDeclIterator(FunDeclCtx->decls_end());
+         i != e;
+         ++i)
+    {
+        MaybeRecordPersistentType(*i);
+    }
+}
+
+void 
+ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
+{
+    if (!D->getIdentifier())
+        return;
+    
+    StringRef name = D->getName();
+    
+    if (name.size() == 0 || name[0] != '$')
+        return;
+    
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    ConstString name_cs(name.str().c_str());
+    
+    if (log)
+        log->Printf ("Recording persistent type %s\n", name_cs.GetCString());
+    
+    Decl *D_scratch = ClangASTContext::CopyDecl(&m_scratch_ast_context, 
+                                                m_ast_context,
+                                                D);
+    
+    TypeDecl *TD_scratch = dyn_cast<TypeDecl>(D_scratch);
+    
+    if (TD_scratch)
+        m_persistent_vars.RegisterPersistentType(name_cs, TD_scratch);
+}
+
 void 
 ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
-{
+{    
     if (m_passthrough)
         m_passthrough->HandleTagDeclDefinition(D);
 }