[Lldb-commits] [lldb] r110777 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangPersistentVariables.h include/lldb/Expression/IRForTarget.h include/lldb/Symbol/TaggedASTType.h include/lldb/Target/Process.h lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpression.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/ClangPersistentVariables.cpp source/Expression/IRForTarget.cpp source/Target/Process.cpp

Sean Callanan scallanan at apple.com
Tue Aug 10 20:57:18 PDT 2010


Author: spyffe
Date: Tue Aug 10 22:57:18 2010
New Revision: 110777

URL: http://llvm.org/viewvc/llvm-project?rev=110777&view=rev
Log:
Added support for persistent variables to the
expression parser.  It is now possible to type:

(lldb) expr int $i = 5; $i + 1
(int) 6
(lldb) expr $i + 2
(int) 7

The skeleton for automatic result variables is
also implemented.  The changes affect:

- the process, which now contains a 
  ClangPersistentVariables object that holds
  persistent variables associated with it
- the expression parser, which now uses
  the persistent variables during variable
  lookup
- TaggedASTType, where I loaded some commonly
  used tags into a header so that they are
  interchangeable between different clients of
  the class

Added:
    lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h
    lldb/trunk/source/Expression/ClangPersistentVariables.cpp
Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/include/lldb/Expression/IRForTarget.h
    lldb/trunk/include/lldb/Symbol/TaggedASTType.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Expression/ClangExpression.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Tue Aug 10 22:57:18 2010
@@ -30,6 +30,7 @@
 
 namespace lldb_private {
 
+class ClangPersistentVariable;
 class ClangPersistentVariables;
 class Error;
 class Function;
@@ -39,8 +40,7 @@
 class ClangExpressionDeclMap
 {
 public:
-    ClangExpressionDeclMap(ExecutionContext *exe_ctx,
-                           ClangPersistentVariables &persistent_vars);
+    ClangExpressionDeclMap(ExecutionContext *exe_ctx);
     ~ClangExpressionDeclMap();
     
     // Interface for ClangStmtVisitor
@@ -48,6 +48,7 @@
                           const clang::Decl *decl);
     
     // Interface for IRForTarget
+    bool AddPersistentVariable (const clang::NamedDecl *decl);
     bool AddValueToStruct (llvm::Value *value,
                            const clang::NamedDecl *decl,
                            std::string &name,
@@ -67,7 +68,6 @@
     bool GetFunctionInfo (const clang::NamedDecl *decl, 
                           llvm::Value**& value, 
                           uint64_t &ptr);
-    
     bool GetFunctionAddress (const char *name,
                              uint64_t &ptr);
     
@@ -90,9 +90,6 @@
     // Interface for ClangASTSource
     void GetDecls (NameSearchContext &context,
                    const char *name);
-
-    typedef TaggedASTType<0> TypeFromParser;
-    typedef TaggedASTType<1> TypeFromUser;
 private:    
     struct Tuple
     {
@@ -124,7 +121,7 @@
     StructMemberVector          m_members;
     ExecutionContext           *m_exe_ctx;
     SymbolContext              *m_sym_ctx; /* owned by ClangExpressionDeclMap */
-    ClangPersistentVariables   &m_persistent_vars;
+    ClangPersistentVariables   *m_persistent_vars;
     off_t                       m_struct_alignment;
     size_t                      m_struct_size;
     bool                        m_struct_laid_out;
@@ -142,6 +139,7 @@
                             TypeFromParser *parser_type = NULL);
     
     void AddOneVariable(NameSearchContext &context, Variable *var);
+    void AddOneVariable(NameSearchContext &context, ClangPersistentVariable *pvar);
     void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym);
     void AddOneType(NameSearchContext &context, Type *type);
     
@@ -150,6 +148,12 @@
                         lldb_private::Value *result_value, /* must be non-NULL if D is set */
                         Error &err);
 
+    bool DoMaterializeOnePersistentVariable(bool dematerialize,
+                                            ExecutionContext &exe_ctx,
+                                            const char *name,
+                                            lldb::addr_t addr,
+                                            Error &err);
+    
     bool DoMaterializeOneVariable(bool dematerialize,
                                   ExecutionContext &exe_ctx,
                                   const SymbolContext &sym_ctx,
@@ -159,11 +163,6 @@
                                   Error &err);
 };
     
-class ClangPersistentVariables
-{
-    
-};
-    
 } // namespace lldb_private
 
 #endif  // liblldb_ClangExpressionDeclMap_h_

Added: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=110777&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (added)
+++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Tue Aug 10 22:57:18 2010
@@ -0,0 +1,89 @@
+//===-- ClangPersistentVariables.h ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ClangPersistentVariables_h_
+#define liblldb_ClangPersistentVariables_h_
+
+#include "lldb-forward-rtti.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Symbol/TaggedASTType.h"
+
+#include <map>
+#include <string>
+
+namespace lldb_private
+{
+
+class ClangPersistentVariable 
+{
+    friend class ClangPersistentVariables;
+public:
+    ClangPersistentVariable () :
+        m_user_type(),
+        m_data()
+    {
+    }
+    
+    ClangPersistentVariable (const ClangPersistentVariable &pv) :
+        m_user_type(pv.m_user_type),
+        m_data(pv.m_data)
+    {
+    }
+    
+    ClangPersistentVariable &operator=(const ClangPersistentVariable &pv)
+    {
+        m_user_type = pv.m_user_type;
+        m_data = pv.m_data;
+        return *this;
+    }
+    
+    size_t Size ()
+    {
+        return (m_user_type.GetClangTypeBitWidth () + 7) / 8;
+    }
+    
+    uint8_t *Data ()
+    {
+        return m_data->GetBytes();
+    }
+    
+    TypeFromUser Type ()
+    {
+        return m_user_type;
+    }
+private:
+    ClangPersistentVariable (TypeFromUser user_type)
+    {
+        m_user_type = user_type;
+        m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0));
+    }
+    TypeFromUser        m_user_type;
+    lldb::DataBufferSP  m_data;
+};
+    
+class ClangPersistentVariables
+{
+public:
+    ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type);
+    ClangPersistentVariable *CreateResultVariable (TypeFromUser user_type);
+    ClangPersistentVariable *GetVariable (ConstString name);
+    
+    ClangPersistentVariables ();
+private:
+    typedef std::map <ConstString, ClangPersistentVariable>    PVarMap;
+    typedef PVarMap::iterator               PVarIterator;
+    
+    PVarMap                                 m_variables;
+    uint64_t                                m_result_counter;
+};
+
+}
+
+#endif
\ No newline at end of file

Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRForTarget.h (original)
+++ lldb/trunk/include/lldb/Expression/IRForTarget.h Tue Aug 10 22:57:18 2010
@@ -46,6 +46,13 @@
     bool rewriteObjCSelectors(llvm::Module &M, 
                               llvm::BasicBlock &BB);
     
+    // pass to find declarations of, and references to, persistent variables and
+    // register them for (de)materialization
+    bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc,
+                                llvm::Module &M);
+    bool rewritePersistentAllocs(llvm::Module &M,
+                                 llvm::BasicBlock &BB);
+    
     // pass to register referenced variables and redirect functions at their
     // targets in the debugged process
     bool MaybeHandleVariable(llvm::Module &M, 

Modified: lldb/trunk/include/lldb/Symbol/TaggedASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TaggedASTType.h?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TaggedASTType.h (original)
+++ lldb/trunk/include/lldb/Symbol/TaggedASTType.h Tue Aug 10 22:57:18 2010
@@ -38,6 +38,10 @@
     }
 };
 
+// Commonly-used tagged types, so code using them is interoperable
+typedef TaggedASTType<0>    TypeFromParser;
+typedef TaggedASTType<1>    TypeFromUser;
+
 }
 
 #endif

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Aug 10 22:57:18 2010
@@ -25,6 +25,7 @@
 #include "lldb/Core/ThreadSafeSTLMap.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Breakpoint/BreakpointSiteList.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/ObjCObjectPrinter.h"
 #include "lldb/Target/ThreadList.h"
@@ -1366,6 +1367,9 @@
     lldb::ProcessSP
     GetSP ();
     
+    ClangPersistentVariables &
+    GetPersistentVariables();
+    
     ObjCObjectPrinter &
     GetObjCObjectPrinter();
 
@@ -1392,6 +1396,7 @@
     Listener                    &m_listener;
     BreakpointSiteList          m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend
                                                         ///< to insert in the target.
+    ClangPersistentVariables    m_persistent_vars;      ///< These are the persistent variables associated with this process for the expression parser.
     UnixSignals                 m_unix_signals;         /// This is the current signal set for this process.
     ConstString                 m_target_triple;
     lldb::ABISP                 m_abi_sp;

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Aug 10 22:57:18 2010
@@ -337,6 +337,8 @@
 		49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; };
 		49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; };
 		49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; };
+		49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */; };
+		49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; };
 		49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; };
 		49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; };
 		49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */; };
@@ -920,6 +922,8 @@
 		49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = "<group>"; };
 		49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = "<group>"; };
 		49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = "<group>"; };
+		49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangPersistentVariables.h; path = include/lldb/Expression/ClangPersistentVariables.h; sourceTree = "<group>"; };
+		49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangPersistentVariables.cpp; path = source/Expression/ClangPersistentVariables.cpp; sourceTree = "<group>"; };
 		49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = "<group>"; };
 		49D7072811B5AD11001AD875 /* ClangASTSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTSource.cpp; path = source/Expression/ClangASTSource.cpp; sourceTree = "<group>"; };
 		49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRToDWARF.cpp; path = source/Expression/IRToDWARF.cpp; sourceTree = "<group>"; };
@@ -1851,6 +1855,8 @@
 				49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */,
 				26BC7DC110F1B79500F91463 /* ClangExpressionVariable.h */,
 				26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */,
+				49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */,
+				49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */,
 				49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */,
 				49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */,
 				26BC7DC210F1B79500F91463 /* ClangStmtVisitor.h */,
@@ -2224,6 +2230,7 @@
 				264723A611FA076E00DE380C /* CleanUp.h in Headers */,
 				2615DB851208A9C90021781D /* StopInfo.h in Headers */,
 				2615DBCB1208B5FC0021781D /* StopInfoMachException.h in Headers */,
+				49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2680,6 +2687,7 @@
 				49E45FAF11F660FE008F7B28 /* ClangASTType.cpp in Sources */,
 				2615DB871208A9E40021781D /* StopInfo.cpp in Sources */,
 				2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */,
+				49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Aug 10 22:57:18 2010
@@ -19,6 +19,7 @@
 #include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/ClangFunction.h"
 #include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Host/Host.h"
@@ -217,8 +218,7 @@
         return false;
     }
     
-    ClangPersistentVariables persistent_vars; /* TODO store this somewhere sensible */
-    ClangExpressionDeclMap expr_decl_map (&m_exe_ctx, persistent_vars);
+    ClangExpressionDeclMap expr_decl_map (&m_exe_ctx);
     ClangExpression clang_expr (target_triple.AsCString (), &expr_decl_map);
     
     //////////////////////////

Modified: lldb/trunk/source/Expression/ClangExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpression.cpp Tue Aug 10 22:57:18 2010
@@ -239,6 +239,7 @@
     m_clang_ap->getLangOpts().ObjC1 = true;
     m_clang_ap->getLangOpts().ThreadsafeStatics = false;
     m_clang_ap->getLangOpts().AccessControl = false; // Debuggers get universal access
+    m_clang_ap->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name
     
     // Set CodeGen options
     m_clang_ap->getCodeGenOpts().EmitDeclMetadata = true;

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Aug 10 22:57:18 2010
@@ -19,6 +19,7 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Expression/ClangASTSource.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
@@ -36,17 +37,17 @@
 using namespace lldb_private;
 using namespace clang;
 
-ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx,
-                                               ClangPersistentVariables &persistent_vars) :
-    m_exe_ctx(exe_ctx),
-    m_persistent_vars(persistent_vars),
-    m_struct_laid_out(false),
+ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
+    m_exe_ctx(exe_ctx),    m_struct_laid_out(false),
     m_materialized_location(0)
 {
     if (exe_ctx && exe_ctx->frame)
         m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
     else
         m_sym_ctx = NULL;
+    
+    if (exe_ctx && exe_ctx->process)
+        m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
 }
 
 ClangExpressionDeclMap::~ClangExpressionDeclMap()
@@ -83,6 +84,31 @@
 // Interface for IRForTarget
 
 bool 
+ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl)
+{
+    clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+    
+    const clang::VarDecl *var(dyn_cast<clang::VarDecl>(decl));
+    
+    if (!var)
+        return false;
+    
+    TypeFromUser user_type(ClangASTContext::CopyType(context, 
+                                                     &var->getASTContext(),
+                                                     var->getType().getAsOpaquePtr()),
+                            context);
+    
+    ConstString const_name(decl->getName().str().c_str());
+    
+    ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type);
+    
+    if (!pvar)
+        return false;
+    
+    return true;
+}
+
+bool 
 ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
                                           const clang::NamedDecl *decl,
                                           std::string &name,
@@ -400,33 +426,40 @@
         
         if (!GetIndexForDecl(tuple_index, iter->m_decl)) 
         {
-            if (iter->m_name.find("___clang_expr_result") == std::string::npos)
+            if (iter->m_name[0] == '$')
             {
-                err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str());
-                return false;
+                if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err))
+                    return false;
             }
-            
-            if (log)
-                log->Printf("Found special result variable %s", iter->m_name.c_str());
-            
-            if (dematerialize)
+            else if (iter->m_name.find("___clang_expr_result") != std::string::npos)
             {
-                clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+                if (log)
+                    log->Printf("Found special result variable %s", iter->m_name.c_str());
                 
-                if (!context)
+                if (dematerialize)
                 {
-                    err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); 
+                    clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
+                    
+                    if (!context)
+                    {
+                        err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); 
+                    }
+                    
+                    TypeFromUser copied_type(ClangASTContext::CopyType(context, 
+                                                                       iter->m_parser_type.GetASTContext(),
+                                                                       iter->m_parser_type.GetOpaqueQualType()),
+                                             context);
+                    
+                    result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType());
+                    
+                    result_value->SetValueType(Value::eValueTypeLoadAddress);
+                    result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset;
                 }
-                
-                TypeFromUser copied_type(ClangASTContext::CopyType(context, 
-                                                                   iter->m_parser_type.GetASTContext(),
-                                                                   iter->m_parser_type.GetOpaqueQualType()),
-                                         context);
-                
-                result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType());
-                
-                result_value->SetValueType(Value::eValueTypeLoadAddress);
-                result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset;
+            }
+            else
+            {
+                err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str());
+                return false;
             }
             
             continue;
@@ -441,6 +474,50 @@
     return true;
 }
 
+bool
+ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
+                                                           ExecutionContext &exe_ctx,
+                                                           const char *name,
+                                                           lldb::addr_t addr,
+                                                           Error &err)
+{
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+    if (log)
+        log->Printf("Found persistent variable %s", name);
+    
+    ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name)));
+    
+    if (!pvar)
+    {
+        err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
+        return LLDB_INVALID_ADDRESS;
+    }
+    
+    size_t pvar_size = pvar->Size();
+    uint8_t *pvar_data = pvar->Data();                
+    Error error;
+    
+    if (dematerialize)
+    {
+        if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
+        {
+            err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
+            return false;
+        }
+    }
+    else 
+    {
+        if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
+        {
+            err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
+            return false;
+        }
+    }
+    
+    return true;
+}
+
 bool 
 ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
                                                  ExecutionContext &exe_ctx,
@@ -682,6 +759,11 @@
     if (var)
         AddOneVariable(context, var);
     
+    ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name)));
+    
+    if (pvar)
+        AddOneVariable(context, pvar);
+    
     /* Commented out pending resolution of a loop when the TagType is imported
     lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
     
@@ -824,6 +906,20 @@
 }
 
 void
+ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
+                                       ClangPersistentVariable *pvar)
+{
+    TypeFromUser user_type = pvar->Type();
+    
+    TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), 
+                                                         user_type.GetASTContext(), 
+                                                         user_type.GetOpaqueQualType()),
+                               context.GetASTContext());
+    
+    (void)context.AddVarDecl(parser_type.GetOpaqueQualType());
+}
+
+void
 ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
                                        Function* fun,
                                        Symbol* symbol)

Added: lldb/trunk/source/Expression/ClangPersistentVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangPersistentVariables.cpp?rev=110777&view=auto
==============================================================================
--- lldb/trunk/source/Expression/ClangPersistentVariables.cpp (added)
+++ lldb/trunk/source/Expression/ClangPersistentVariables.cpp Tue Aug 10 22:57:18 2010
@@ -0,0 +1,59 @@
+//===-- ClangPersistentVariables.cpp ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangPersistentVariables.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+
+using namespace lldb_private;
+using namespace clang;
+
+ClangPersistentVariables::ClangPersistentVariables () :
+    m_variables(),
+    m_result_counter(0)
+{
+}
+
+ClangPersistentVariable *
+ClangPersistentVariables::CreateVariable (ConstString name, 
+                                          TypeFromUser user_type)
+{    
+    ClangPersistentVariable new_var(user_type);
+    
+    if (m_variables.find(name) != m_variables.end())
+        return NULL;
+    
+    m_variables[name] = new_var;
+    
+    return &m_variables[name];
+}
+
+ClangPersistentVariable *
+ClangPersistentVariables::CreateResultVariable (TypeFromUser user_type)
+{    
+    StreamString s;
+    s.Printf("$%llu", m_result_counter);
+    ConstString name(s.GetString().c_str());
+    
+    ClangPersistentVariable *ret = CreateVariable (name, user_type);
+    
+    if (ret != NULL)
+        ++m_result_counter;
+    
+    return ret;
+}
+
+ClangPersistentVariable *
+ClangPersistentVariables::GetVariable (ConstString name)
+{    
+    if (m_variables.find(name) == m_variables.end())
+        return NULL;
+    
+    return &m_variables[name];
+}

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Tue Aug 10 22:57:18 2010
@@ -37,6 +37,20 @@
 {
 }
 
+/* A handy utility function used at several places in the code */
+
+static std::string 
+PrintValue(Value *V, bool truncate = false)
+{
+    std::string s;
+    raw_string_ostream rso(s);
+    V->print(rso);
+    rso.flush();
+    if (truncate)
+        s.resize(s.length() - 1);
+    return s;
+}
+
 IRForTarget::~IRForTarget()
 {
 }
@@ -200,6 +214,97 @@
     return true;
 }
 
+bool 
+IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc,
+                                    llvm::Module &M)
+{
+    AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
+    
+    MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
+
+    if (!alloc_md || !alloc_md->getNumOperands())
+        return false;
+    
+    ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0));
+    
+    if (!constant_int)
+        return false;
+    
+    // We attempt to register this as a new persistent variable with the DeclMap.
+    
+    uintptr_t ptr = constant_int->getZExtValue();
+    
+    clang::NamedDecl *decl = reinterpret_cast<clang::NamedDecl *>(ptr);
+    
+    if (!m_decl_map->AddPersistentVariable(decl))
+        return false;
+    
+    GlobalVariable *persistent_global = new GlobalVariable(M, 
+                                                           alloc->getType()->getElementType(),
+                                                           false, /* not constant */
+                                                           GlobalValue::ExternalLinkage,
+                                                           NULL, /* no initializer */
+                                                           alloc->getName().str().c_str());
+    
+    // What we're going to do here is make believe this was a regular old external
+    // variable.  That means we need to make the metadata valid.
+    
+    NamedMDNode *named_metadata = M.getNamedMetadata("clang.global.decl.ptrs");
+    
+    llvm::Value* values[2];
+    values[0] = persistent_global;
+    values[1] = constant_int;
+
+    MDNode *persistent_global_md = MDNode::get(M.getContext(), values, 2);
+    named_metadata->addOperand(persistent_global_md);
+    
+    alloc->replaceAllUsesWith(persistent_global);
+    alloc->eraseFromParent();
+    
+    return true;
+}
+
+bool 
+IRForTarget::rewritePersistentAllocs(llvm::Module &M,
+                                     llvm::BasicBlock &BB)
+{
+    lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+    
+    BasicBlock::iterator ii;
+    
+    typedef SmallVector <Instruction*, 2> InstrList;
+    typedef InstrList::iterator InstrIterator;
+    
+    InstrList pvar_allocs;
+    
+    for (ii = BB.begin();
+         ii != BB.end();
+         ++ii)
+    {
+        Instruction &inst = *ii;
+        
+        if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
+            if (alloc->getName().startswith("$"))
+                pvar_allocs.push_back(alloc);
+    }
+    
+    InstrIterator iter;
+    
+    for (iter = pvar_allocs.begin();
+         iter != pvar_allocs.end();
+         ++iter)
+    {
+        if (!RewritePersistentAlloc(*iter, M))
+        {
+            if(log)
+                log->PutCString("Couldn't rewrite the creation of a persistent variable");
+            return false;
+        }
+    }
+    
+    return true;
+}
+
 static clang::NamedDecl *
 DeclForGlobalValue(Module &module,
                    GlobalValue *global_value)
@@ -222,7 +327,7 @@
             return NULL;
         
         if (metadata_node->getNumOperands() != 2)
-            return NULL;
+            continue;
         
         if (metadata_node->getOperand(0) != global_value)
             continue;
@@ -400,18 +505,6 @@
     return true;
 }
 
-static std::string 
-PrintValue(Value *V, bool truncate = false)
-{
-    std::string s;
-    raw_string_ostream rso(s);
-    V->print(rso);
-    rso.flush();
-    if (truncate)
-        s.resize(s.length() - 1);
-    return s;
-}
-
 static bool isGuardVariableRef(Value *V)
 {
     ConstantExpr *C = dyn_cast<ConstantExpr>(V);
@@ -518,12 +611,21 @@
 
     Value::use_iterator ui;
     
+    SmallVector<User*, 16> users;
+    
+    // We do this because the use list might change, invalidating our iterator.
+    // Much better to keep a work list ourselves.
     for (ui = C->use_begin();
          ui != C->use_end();
          ++ui)
-    {
-        User *user = *ui;
+        users.push_back(*ui);
         
+    for (int i = 0;
+         i < users.size();
+         ++i)
+    {
+        User *user = users[i];
+                
         if (Constant *constant = dyn_cast<Constant>(user))
         {
             // synthesize a new non-constant equivalent of the constant
@@ -703,9 +805,12 @@
          bbi != function->end();
          ++bbi)
     {
-        if (!rewriteObjCSelectors(M, *bbi))
+        if (!rewritePersistentAllocs(M, *bbi))
             return false;
         
+        if (!rewriteObjCSelectors(M, *bbi))
+            return false;
+
         if (!resolveExternals(M, *bbi))
             return false;
         
@@ -713,13 +818,6 @@
             return false;
     }
     
-    ///////////////////////////////
-    // Run function-level passes
-    //
-    
-    if (!replaceVariables(M, *function))
-        return false;
-    
     if (log)
     {
         std::string s;
@@ -732,6 +830,13 @@
         log->Printf("Module after preparing for execution: \n%s", s.c_str());
     }
     
+    ///////////////////////////////
+    // Run function-level passes
+    //
+    
+    if (!replaceVariables(M, *function))
+        return false;
+    
     return true;    
 }
 

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=110777&r1=110776&r2=110777&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Aug 10 22:57:18 2010
@@ -80,7 +80,8 @@
     m_notifications (),
     m_listener(listener),
     m_unix_signals (),
-    m_objc_object_printer(*this)
+    m_objc_object_printer(*this),
+    m_persistent_vars()
 {
     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
     if (log)
@@ -1882,6 +1883,12 @@
     return GetTarget().GetProcessSP();
 }
 
+ClangPersistentVariables &
+Process::GetPersistentVariables()
+{
+    return m_persistent_vars;
+}
+
 ObjCObjectPrinter &
 Process::GetObjCObjectPrinter()
 {





More information about the lldb-commits mailing list