Added support for the fragile ivars provided by
Apple's Objective-C 2.0 runtime.  They are enabled
if the Objective-C runtime has the proper version.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@123694 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index 08468fa..f996242 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -452,6 +452,36 @@
     return true;
 }
 
+bool 
+ClangExpressionDeclMap::GetSymbolAddress
+(
+    const ConstString &name,
+    uint64_t &ptr
+)
+{
+    assert (m_parser_vars.get());
+    
+    // Back out in all cases where we're not fully initialized
+    if (m_parser_vars->m_exe_ctx->target == NULL)
+        return false;
+    
+    SymbolContextList sc_list;
+    
+    m_parser_vars->m_exe_ctx->target->GetImages().FindSymbolsWithNameAndType(name, lldb::eSymbolTypeAny, sc_list);
+    
+    if (!sc_list.GetSize())
+        return false;
+    
+    SymbolContext sym_ctx;
+    sc_list.GetContextAtIndex(0, sym_ctx);
+    
+    const Address *sym_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
+    
+    ptr = sym_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
+    
+    return true;
+}
+
 // Interface for CommandObjectExpression
 
 bool 
diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp
index 77fff8a..adc5a9e 100644
--- a/source/Expression/ClangExpressionParser.cpp
+++ b/source/Expression/ClangExpressionParser.cpp
@@ -21,6 +21,7 @@
 #include "lldb/Expression/IRToDWARF.h"
 #include "lldb/Expression/RecordingMemoryManager.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
@@ -177,6 +178,7 @@
 //===----------------------------------------------------------------------===//
 
 ClangExpressionParser::ClangExpressionParser(const char *target_triple,
+                                             Process *process,
                                              ClangExpression &expr) :
     m_expr(expr),
     m_target_triple (),
@@ -211,10 +213,18 @@
     // Setup objective C
     m_compiler->getLangOpts().ObjC1 = true;
     m_compiler->getLangOpts().ObjC2 = true;
-    // We need to enable the fragile ABI for things target triples that
-    // support it. 
-//    m_compiler->getLangOpts().ObjCNonFragileABI = true;     // NOT i386
-//    m_compiler->getLangOpts().ObjCNonFragileABI2 = true;    // NOT i386
+    
+    if (process)
+    {
+        if (process->GetObjCLanguageRuntime())
+        {
+            if (process->GetObjCLanguageRuntime()->GetRuntimeVersion() == lldb::eAppleObjC_V2)
+            {
+                m_compiler->getLangOpts().ObjCNonFragileABI = true;     // NOT i386
+                m_compiler->getLangOpts().ObjCNonFragileABI2 = true;    // NOT i386
+            }
+        }
+    }
 
     m_compiler->getLangOpts().ThreadsafeStatics = false;
     m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access
diff --git a/source/Expression/ClangFunction.cpp b/source/Expression/ClangFunction.cpp
index e55238d..d2435a7 100644
--- a/source/Expression/ClangFunction.cpp
+++ b/source/Expression/ClangFunction.cpp
@@ -214,7 +214,7 @@
         
     // Okay, now compile this expression
     
-    m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this));
+    m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), NULL, *this));
     
     num_errors = m_parser->Parse (errors);
     
diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index a528181..13d5ab9 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -253,7 +253,7 @@
     
     m_expr_decl_map->WillParse(exe_ctx);
     
-    ClangExpressionParser parser(target_triple.GetCString(), *this);
+    ClangExpressionParser parser(target_triple.GetCString(), exe_ctx.process, *this);
     
     unsigned num_errors = parser.Parse (error_stream);
     
diff --git a/source/Expression/ClangUtilityFunction.cpp b/source/Expression/ClangUtilityFunction.cpp
index 6b47768..f682e36 100644
--- a/source/Expression/ClangUtilityFunction.cpp
+++ b/source/Expression/ClangUtilityFunction.cpp
@@ -105,7 +105,7 @@
     
     m_expr_decl_map->WillParse(exe_ctx);
         
-    ClangExpressionParser parser(target_triple.GetCString(), *this);
+    ClangExpressionParser parser(target_triple.GetCString(), exe_ctx.process, *this);
     
     unsigned num_errors = parser.Parse (error_stream);
     
diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp
index dc557ca..bdcb225 100644
--- a/source/Expression/IRForTarget.cpp
+++ b/source/Expression/IRForTarget.cpp
@@ -1070,6 +1070,44 @@
 }
 
 bool
+IRForTarget::HandleSymbol (Module &llvm_module,
+                           Value *symbol)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    lldb_private::ConstString name(symbol->getName().str().c_str());
+    
+    uint64_t symbol_addr;
+    
+    if (!m_decl_map->GetSymbolAddress (name, symbol_addr))
+    {
+        if (log)
+            log->Printf ("Symbol \"%s\" had no address", name.GetCString());
+        
+        return false;
+    }
+
+    if (log)
+        log->Printf("Found \"%s\" at 0x%llx", name.GetCString(), symbol_addr);
+    
+    const Type *symbol_type = symbol->getType();
+    
+    const IntegerType *intptr_ty = Type::getIntNTy(llvm_module.getContext(),
+                                                   (llvm_module.getPointerSize() == Module::Pointer64) ? 64 : 32);
+    
+    Constant *symbol_addr_int = ConstantInt::get(intptr_ty, symbol_addr, false);
+    
+    Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
+    
+    if (log)
+        log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());
+    
+    symbol->replaceAllUsesWith(symbol_addr_ptr);
+    
+    return true;
+}
+
+bool
 IRForTarget::MaybeHandleCallArguments (Module &llvm_module, CallInst *Old)
 {
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -1250,9 +1288,16 @@
                         (*global).getName().str().c_str(),
                         DeclForGlobalValue(llvm_module, global));
     
-        if (DeclForGlobalValue(llvm_module, global) &&
-            !MaybeHandleVariable (llvm_module, global))
-            return false;
+        if ((*global).getName().str().find("OBJC_IVAR") == 0)
+        {
+            if (!HandleSymbol(llvm_module, global))
+                return false;
+        }
+        else if (DeclForGlobalValue(llvm_module, global))
+        {
+            if (!MaybeHandleVariable (llvm_module, global))
+                return false;
+        }
     }
         
     return true;